mirror of
https://github.com/openai/whisper.git
synced 2025-11-28 08:11:11 +00:00
Merge de129929f03b0c22403158a87857d48369b95ef1 into c0d2f624c09dc18e709e37c2ad90c039a4eb72a2
This commit is contained in:
commit
0cbd417946
15
.claude/settings.local.json
Normal file
15
.claude/settings.local.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"permissions": {
|
||||||
|
"allow": [
|
||||||
|
"Bash(python -m pip:*)",
|
||||||
|
"Bash(where python)",
|
||||||
|
"Bash(python:*)",
|
||||||
|
"Read(//c/Users/Dan Zambello/.claude/agents/**)",
|
||||||
|
"Read(//c/Users/Dan Zambello/.claude/**)",
|
||||||
|
"mcp__browsermcp__browser_snapshot",
|
||||||
|
"mcp__browsermcp__browser_click"
|
||||||
|
],
|
||||||
|
"deny": [],
|
||||||
|
"ask": []
|
||||||
|
}
|
||||||
|
}
|
||||||
76
CLAUDE.md
Normal file
76
CLAUDE.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is OpenAI's Whisper repository - a general-purpose speech recognition model that performs multilingual speech recognition, speech translation, and language identification. The codebase is built as a Python package with PyTorch.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
- **whisper/__init__.py**: Main entry point with model loading (`load_model()`) and available models registry
|
||||||
|
- **whisper/model.py**: Core Whisper transformer model implementation
|
||||||
|
- **whisper/transcribe.py**: High-level transcription interface with CLI entry point
|
||||||
|
- **whisper/decoding.py**: Lower-level decoding logic and options
|
||||||
|
- **whisper/audio.py**: Audio processing utilities (loading, mel spectrograms, padding)
|
||||||
|
- **whisper/tokenizer.py**: Text tokenization and language handling
|
||||||
|
- **whisper/normalizers/**: Text normalization for different languages
|
||||||
|
|
||||||
|
### Model Architecture
|
||||||
|
- Transformer sequence-to-sequence model
|
||||||
|
- Multiple model sizes: tiny, base, small, medium, large, turbo
|
||||||
|
- Both English-only (.en) and multilingual variants
|
||||||
|
- Models downloaded from Azure CDN and cached locally
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
```bash
|
||||||
|
pytest # Run all tests
|
||||||
|
pytest tests/test_*.py # Run specific test file
|
||||||
|
pytest -m requires_cuda # Run CUDA-specific tests
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Quality
|
||||||
|
```bash
|
||||||
|
black . # Format code
|
||||||
|
isort . # Sort imports
|
||||||
|
flake8 # Lint code
|
||||||
|
pre-commit run --all-files # Run all pre-commit hooks
|
||||||
|
```
|
||||||
|
|
||||||
|
### Installation for Development
|
||||||
|
```bash
|
||||||
|
pip install -e .[dev] # Install in development mode with dev dependencies
|
||||||
|
```
|
||||||
|
|
||||||
|
## Package Structure
|
||||||
|
|
||||||
|
- Built using setuptools with pyproject.toml configuration
|
||||||
|
- Entry point: `whisper` command maps to `whisper.transcribe:cli`
|
||||||
|
- Dependencies: torch, numpy, tiktoken, tqdm, numba, more-itertools
|
||||||
|
- Optional triton dependency for Linux x86_64 optimization
|
||||||
|
|
||||||
|
## Key APIs
|
||||||
|
|
||||||
|
### High-level Usage
|
||||||
|
```python
|
||||||
|
import whisper
|
||||||
|
model = whisper.load_model("turbo")
|
||||||
|
result = model.transcribe("audio.mp3")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lower-level Usage
|
||||||
|
```python
|
||||||
|
audio = whisper.load_audio("audio.mp3")
|
||||||
|
mel = whisper.log_mel_spectrogram(audio)
|
||||||
|
result = whisper.decode(model, mel, options)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Notes
|
||||||
|
|
||||||
|
- Tests use pytest with custom markers for CUDA requirements
|
||||||
|
- Random seeds fixed for reproducibility (seed=42)
|
||||||
|
- Test coverage includes audio processing, normalization, timing, tokenization, and transcription
|
||||||
137
README_SETUP.md
Normal file
137
README_SETUP.md
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
# Voice to Text Converter - Setup Guide
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Windows 10/11
|
||||||
|
- Internet connection (for initial setup)
|
||||||
|
- Microphone access
|
||||||
|
|
||||||
|
### Installation Steps
|
||||||
|
|
||||||
|
1. **Install Python** (if not already installed)
|
||||||
|
- Download from [python.org](https://python.org)
|
||||||
|
- **IMPORTANT**: Check "Add Python to PATH" during installation
|
||||||
|
- Minimum version: Python 3.8
|
||||||
|
|
||||||
|
2. **Run Setup**
|
||||||
|
- Double-click `setup.bat`
|
||||||
|
- Wait for dependencies to install (may take 5-10 minutes)
|
||||||
|
- Setup is complete when you see "Setup Complete!"
|
||||||
|
|
||||||
|
3. **Start Using**
|
||||||
|
- **GUI Mode**: Double-click `voice_to_text_gui.bat`
|
||||||
|
- **Terminal Mode**: Double-click `voice_to_text_terminal.bat`
|
||||||
|
|
||||||
|
## Usage Modes
|
||||||
|
|
||||||
|
### GUI Mode (Recommended)
|
||||||
|
- **Launch**: `voice_to_text_gui.bat` (batch window closes, GUI stays open)
|
||||||
|
- **Features**:
|
||||||
|
- Visual interface with buttons
|
||||||
|
- F1 global hotkey for recording
|
||||||
|
- Always on top option
|
||||||
|
- System tray integration
|
||||||
|
- Settings dialog
|
||||||
|
- **Best for**: Daily use and continuous workflow
|
||||||
|
|
||||||
|
### Terminal Mode
|
||||||
|
- **Launch**: `voice_to_text_terminal.bat`
|
||||||
|
- **Features**:
|
||||||
|
- Simple text interface
|
||||||
|
- Press Enter to stop recording
|
||||||
|
- Lightweight and fast
|
||||||
|
- **Best for**: Quick one-off recordings
|
||||||
|
|
||||||
|
## Creating Desktop Shortcuts
|
||||||
|
|
||||||
|
1. **Right-click** on desktop → **New** → **Shortcut**
|
||||||
|
2. **Browse** to the batch file you want (e.g., `voice_to_text_gui.bat`)
|
||||||
|
3. **Name** the shortcut (e.g., "Voice to Text")
|
||||||
|
4. **Optional**: Right-click shortcut → **Properties** → **Change Icon**
|
||||||
|
|
||||||
|
## First Run
|
||||||
|
|
||||||
|
- **Model Download**: First run will download Whisper model (~150MB)
|
||||||
|
- **Microphone Permission**: Windows may ask for microphone access
|
||||||
|
- **Settings**: GUI mode creates `voice_to_text_settings.json` for preferences
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
voice-to-text/
|
||||||
|
├── voice_to_text.py # Main application
|
||||||
|
├── setup.bat # One-time setup
|
||||||
|
├── voice_to_text_gui.bat # GUI launcher
|
||||||
|
├── voice_to_text_terminal.bat # Terminal launcher
|
||||||
|
├── requirements.txt # Python dependencies
|
||||||
|
├── transcripts/ # Saved transcriptions
|
||||||
|
├── voice_to_text_settings.json # Settings (created after first GUI run)
|
||||||
|
└── README_SETUP.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Voice Commands
|
||||||
|
|
||||||
|
The system automatically converts natural speech into Claude Code prompts:
|
||||||
|
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| "use agent python pro" | `@agent python-pro` |
|
||||||
|
| "run tool bash" | `@tool bash` |
|
||||||
|
| "file package.json" | `@file package.json` |
|
||||||
|
| "directory source" | `@dir source/` |
|
||||||
|
| "function get user" | `` `getUser()` function`` |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "Python is not installed"
|
||||||
|
- Install Python from [python.org](https://python.org)
|
||||||
|
- **Must check "Add Python to PATH"** during installation
|
||||||
|
- Restart command prompt/computer after installation
|
||||||
|
|
||||||
|
### "Failed to install dependencies"
|
||||||
|
- Check internet connection
|
||||||
|
- Try running `setup.bat` as administrator
|
||||||
|
- Manually run: `pip install -r requirements.txt`
|
||||||
|
|
||||||
|
### "No audio recorded"
|
||||||
|
- Check microphone permissions in Windows Settings
|
||||||
|
- Ensure microphone is not muted
|
||||||
|
- Try a different microphone
|
||||||
|
|
||||||
|
### "Poor transcription accuracy"
|
||||||
|
- Speak clearly and at normal pace
|
||||||
|
- Reduce background noise
|
||||||
|
- Move closer to microphone
|
||||||
|
- In GUI mode: Settings → Change to larger Whisper model
|
||||||
|
|
||||||
|
### GUI Hotkey Not Working
|
||||||
|
- Check if another application is using F1
|
||||||
|
- Try running as administrator
|
||||||
|
- Change hotkey in Settings dialog
|
||||||
|
|
||||||
|
### System Tray Issues
|
||||||
|
- If tray doesn't work, app falls back to normal minimize
|
||||||
|
- Some Windows configurations don't support system tray
|
||||||
|
- This doesn't affect core functionality
|
||||||
|
|
||||||
|
## Advanced Settings (GUI Mode)
|
||||||
|
|
||||||
|
Access via Settings button:
|
||||||
|
- **Global Hotkey**: Change from F1 to F2-F12
|
||||||
|
- **Whisper Model**: tiny (fast) to large (accurate)
|
||||||
|
- **Always on Top**: Keep window visible
|
||||||
|
- **Auto Copy**: Automatically copy to clipboard
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- Check transcripts in `/transcripts` folder
|
||||||
|
- Settings saved in `voice_to_text_settings.json`
|
||||||
|
- For issues, check the console output in terminal mode
|
||||||
|
|
||||||
|
## Updates
|
||||||
|
|
||||||
|
To update the application:
|
||||||
|
1. Replace `voice_to_text.py` with new version
|
||||||
|
2. Update `requirements.txt` if needed
|
||||||
|
3. Run `setup.bat` again if dependencies changed
|
||||||
153
assessment_analysis.json
Normal file
153
assessment_analysis.json
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
{
|
||||||
|
"Q1": {
|
||||||
|
"question": "What is the purpose of determining and documenting requirements for a cabinet installation?",
|
||||||
|
"transcribed_answer": "To complete it accurately and efficiently, including detailed specification for the cabinets and all components.",
|
||||||
|
"written_summary": "To have a better understanding of the project for all persons involved and plan in advance for any difficulties and refer to documents as a guide for future projects.",
|
||||||
|
"assessment": {
|
||||||
|
"word_count": 15,
|
||||||
|
"has_substantial_content": true,
|
||||||
|
"keyword_relevance": 0.2857142857142857,
|
||||||
|
"transcription_summary_match": 0.15151515151515152
|
||||||
|
},
|
||||||
|
"transcription_details": {
|
||||||
|
"text": "To complete it accurately and efficiently, including detailed specification for the cabinets and all components.",
|
||||||
|
"language": "en",
|
||||||
|
"segments": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"seek": 0,
|
||||||
|
"start": 0.0,
|
||||||
|
"end": 8.0,
|
||||||
|
"text": " To complete it accurately and efficiently, including detailed specification for the cabinets and all components.",
|
||||||
|
"tokens": [
|
||||||
|
50364,
|
||||||
|
1407,
|
||||||
|
3566,
|
||||||
|
309,
|
||||||
|
20095,
|
||||||
|
293,
|
||||||
|
19621,
|
||||||
|
11,
|
||||||
|
3009,
|
||||||
|
9942,
|
||||||
|
31256,
|
||||||
|
337,
|
||||||
|
264,
|
||||||
|
37427,
|
||||||
|
293,
|
||||||
|
439,
|
||||||
|
6677,
|
||||||
|
13,
|
||||||
|
50764
|
||||||
|
],
|
||||||
|
"temperature": 0.0,
|
||||||
|
"avg_logprob": -0.3367410898208618,
|
||||||
|
"compression_ratio": 1.1914893617021276,
|
||||||
|
"no_speech_prob": 0.07899459451436996
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Q2": {
|
||||||
|
"error": "File not found: 77914809189__571E73A4-D2E8-4B00-934C-5B2E54DE47A4.MOV"
|
||||||
|
},
|
||||||
|
"Q3": {
|
||||||
|
"question": "What information is found in the appliance manuals?",
|
||||||
|
"transcribed_answer": "It's including product identifications, safety warnings and precautions step by step operating instructions, installation and assembly instructions. My tenants got lined, troubleshooting tips, technical specifications and warranty information.",
|
||||||
|
"written_summary": "Fitting instructions and requirements",
|
||||||
|
"assessment": {
|
||||||
|
"word_count": 28,
|
||||||
|
"has_substantial_content": true,
|
||||||
|
"keyword_relevance": 0.25,
|
||||||
|
"transcription_summary_match": 0.03571428571428571
|
||||||
|
},
|
||||||
|
"transcription_details": {
|
||||||
|
"text": "It's including product identifications, safety warnings and precautions step by step operating instructions, installation and assembly instructions. My tenants got lined, troubleshooting tips, technical specifications and warranty information.",
|
||||||
|
"language": "en",
|
||||||
|
"segments": [
|
||||||
|
{
|
||||||
|
"id": 0,
|
||||||
|
"seek": 0,
|
||||||
|
"start": 0.0,
|
||||||
|
"end": 7.0,
|
||||||
|
"text": " It's including product identifications, safety warnings and precautions",
|
||||||
|
"tokens": [
|
||||||
|
50364,
|
||||||
|
467,
|
||||||
|
311,
|
||||||
|
3009,
|
||||||
|
1674,
|
||||||
|
2473,
|
||||||
|
7833,
|
||||||
|
11,
|
||||||
|
4514,
|
||||||
|
30009,
|
||||||
|
293,
|
||||||
|
34684,
|
||||||
|
50714
|
||||||
|
],
|
||||||
|
"temperature": 0.0,
|
||||||
|
"avg_logprob": -0.3135071884502064,
|
||||||
|
"compression_ratio": 1.5576923076923077,
|
||||||
|
"no_speech_prob": 0.02320166677236557
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"seek": 0,
|
||||||
|
"start": 7.0,
|
||||||
|
"end": 13.0,
|
||||||
|
"text": " step by step operating instructions, installation and assembly instructions.",
|
||||||
|
"tokens": [
|
||||||
|
50714,
|
||||||
|
1823,
|
||||||
|
538,
|
||||||
|
1823,
|
||||||
|
7447,
|
||||||
|
9415,
|
||||||
|
11,
|
||||||
|
13260,
|
||||||
|
293,
|
||||||
|
12103,
|
||||||
|
9415,
|
||||||
|
13,
|
||||||
|
51014
|
||||||
|
],
|
||||||
|
"temperature": 0.0,
|
||||||
|
"avg_logprob": -0.3135071884502064,
|
||||||
|
"compression_ratio": 1.5576923076923077,
|
||||||
|
"no_speech_prob": 0.02320166677236557
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"seek": 0,
|
||||||
|
"start": 13.0,
|
||||||
|
"end": 21.0,
|
||||||
|
"text": " My tenants got lined, troubleshooting tips, technical specifications and warranty information.",
|
||||||
|
"tokens": [
|
||||||
|
51014,
|
||||||
|
1222,
|
||||||
|
31216,
|
||||||
|
658,
|
||||||
|
17189,
|
||||||
|
11,
|
||||||
|
15379,
|
||||||
|
47011,
|
||||||
|
6082,
|
||||||
|
11,
|
||||||
|
6191,
|
||||||
|
29448,
|
||||||
|
293,
|
||||||
|
26852,
|
||||||
|
1589,
|
||||||
|
13,
|
||||||
|
51414
|
||||||
|
],
|
||||||
|
"temperature": 0.0,
|
||||||
|
"avg_logprob": -0.3135071884502064,
|
||||||
|
"compression_ratio": 1.5576923076923077,
|
||||||
|
"no_speech_prob": 0.02320166677236557
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
405
assessment_system_architecture.md
Normal file
405
assessment_system_architecture.md
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
# Assessment Processing System Architecture & Implementation Guide
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
This document outlines the comprehensive architecture and implementation plan for an automated assessment processing system that builds on the existing OpenAI Whisper transcription capabilities. The system will automatically identify, extract, process, and analyze educational assessments from web platforms like aXcelerate LMS.
|
||||||
|
|
||||||
|
## System Overview
|
||||||
|
|
||||||
|
The assessment processing platform provides:
|
||||||
|
- Automatic assessment type identification (competency conversations, assignments, etc.)
|
||||||
|
- Question and answer extraction from web pages
|
||||||
|
- Media file processing (audio transcription, video compilation)
|
||||||
|
- Intelligent quality assessment of student responses
|
||||||
|
- Integration with learning resources and regulatory documentation
|
||||||
|
- Automated report generation for assessors
|
||||||
|
- Future capability for automated marking
|
||||||
|
|
||||||
|
## Python-Pro Agent Recommendations
|
||||||
|
|
||||||
|
### Architecture & Design Patterns
|
||||||
|
|
||||||
|
**Recommended Approach**: Domain-Driven Design (DDD) with Clean Architecture principles
|
||||||
|
- **Modular Monolith**: Start with clear service boundaries, evolve to microservices as needed
|
||||||
|
- **Event Sourcing**: For workflow orchestration and audit trail
|
||||||
|
- **Plugin Architecture**: Extensible system for new assessment types and quality metrics
|
||||||
|
|
||||||
|
### Modern Python Stack (3.12+)
|
||||||
|
|
||||||
|
**Core Technologies**:
|
||||||
|
- **Framework**: FastAPI with asyncio for high-performance async processing
|
||||||
|
- **Data Validation**: Pydantic v2 for robust type safety and validation
|
||||||
|
- **Database**: SQLAlchemy 2.0 with async support
|
||||||
|
- **Task Queue**: Celery with Redis for background processing
|
||||||
|
- **Testing**: pytest with async test support
|
||||||
|
|
||||||
|
**Dependency Management**:
|
||||||
|
- **Package Manager**: uv for fast dependency resolution
|
||||||
|
- **Code Quality**: ruff for linting, mypy for type checking
|
||||||
|
- **Pre-commit**: Automated code quality checks
|
||||||
|
|
||||||
|
### Data Modeling Approach
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Core domain models structure
|
||||||
|
class AssessmentType(Enum):
|
||||||
|
COMPETENCY_CONVERSATION = "competency_conversation"
|
||||||
|
ASSIGNMENT = "assignment"
|
||||||
|
PRACTICAL_ASSESSMENT = "practical_assessment"
|
||||||
|
THEORY_EXAM = "theory_exam"
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AssessmentQuestion:
|
||||||
|
question_id: str
|
||||||
|
question_text: str
|
||||||
|
expected_criteria: List[str]
|
||||||
|
media_requirements: Optional[Dict]
|
||||||
|
weight: float
|
||||||
|
|
||||||
|
class Assessment:
|
||||||
|
def __init__(self, assessment_id: str, assessment_type: AssessmentType):
|
||||||
|
self.assessment_id = assessment_id
|
||||||
|
self.assessment_type = assessment_type
|
||||||
|
self.questions: List[AssessmentQuestion] = []
|
||||||
|
self.student_responses: Dict[str, 'StudentResponse'] = {}
|
||||||
|
self.quality_scores: Dict[str, float] = {}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Media Processing Pipeline
|
||||||
|
|
||||||
|
**Enhanced Whisper Integration**:
|
||||||
|
- Refactor existing `voice_to_text.py` into modular async service
|
||||||
|
- Support for video-to-audio conversion
|
||||||
|
- Batch processing capabilities
|
||||||
|
- Caching of transcription results
|
||||||
|
|
||||||
|
**Video Processing Features**:
|
||||||
|
- Question-based video segmentation
|
||||||
|
- Watermark and title overlay system
|
||||||
|
- Compilation into assessment-specific videos
|
||||||
|
- Multiple format support (MOV, MP4, etc.)
|
||||||
|
|
||||||
|
### Quality Assessment Algorithms
|
||||||
|
|
||||||
|
**Multi-dimensional Analysis**:
|
||||||
|
1. **Semantic Similarity**: Using sentence transformers for content relevance
|
||||||
|
2. **Keyword Relevance**: Domain-specific terminology matching
|
||||||
|
3. **Coherence Scoring**: Logical flow and structure analysis
|
||||||
|
4. **Completeness Assessment**: Coverage of required criteria
|
||||||
|
5. **Technical Accuracy**: Integration with regulatory documentation
|
||||||
|
|
||||||
|
**Advanced Metrics**:
|
||||||
|
- Confidence scoring with uncertainty quantification
|
||||||
|
- Comparative analysis against model answers
|
||||||
|
- Progressive improvement tracking
|
||||||
|
- Bias detection and mitigation
|
||||||
|
|
||||||
|
### Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
assessment_processor/
|
||||||
|
├── src/
|
||||||
|
│ ├── domain/ # Core business logic
|
||||||
|
│ │ ├── assessment/ # Assessment aggregate
|
||||||
|
│ │ ├── media/ # Media processing domain
|
||||||
|
│ │ └── quality/ # Quality assessment domain
|
||||||
|
│ ├── application/ # Use cases and services
|
||||||
|
│ │ ├── services/ # Application services
|
||||||
|
│ │ └── use_cases/ # Business use cases
|
||||||
|
│ ├── infrastructure/ # External concerns
|
||||||
|
│ │ ├── repositories/ # Data persistence
|
||||||
|
│ │ ├── adapters/ # External system adapters
|
||||||
|
│ │ └── events/ # Event handling
|
||||||
|
│ └── presentation/ # API and UI layers
|
||||||
|
│ ├── api/ # REST API endpoints
|
||||||
|
│ └── cli/ # Command-line interface
|
||||||
|
├── tests/ # Test suites
|
||||||
|
├── docs/ # Documentation
|
||||||
|
└── pyproject.toml # Project configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architect-Review Agent Recommendations
|
||||||
|
|
||||||
|
### High-Level System Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Assessment Processing Platform │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||||
|
│ │ Assessment │ │ Media │ │ Quality │ │
|
||||||
|
│ │ Discovery │ │ Processing │ │ Assessment │ │
|
||||||
|
│ │ Domain │ │ Domain │ │ Domain │ │
|
||||||
|
│ └──────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
|
||||||
|
│ │ Integration │ │ Reporting │ │ Workflow │ │
|
||||||
|
│ │ Domain │ │ Domain │ │ Orchestration │ │
|
||||||
|
│ │ │ │ │ │ Domain │ │
|
||||||
|
│ └──────────────────┘ └─────────────────┘ └─────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Boundaries & Core Services
|
||||||
|
|
||||||
|
**Assessment Discovery Service**:
|
||||||
|
- Browser automation using MCP tools
|
||||||
|
- aXcelerate LMS integration
|
||||||
|
- Assessment type classification
|
||||||
|
- Question and answer extraction
|
||||||
|
|
||||||
|
**Media Processing Service**:
|
||||||
|
- Enhanced Whisper transcription
|
||||||
|
- Video processing and compilation
|
||||||
|
- File storage and organization
|
||||||
|
- Concurrent processing pipeline
|
||||||
|
|
||||||
|
**Quality Assessment Service**:
|
||||||
|
- Plugin-based assessment algorithms
|
||||||
|
- External resource integration
|
||||||
|
- Confidence scoring
|
||||||
|
- Comparative analysis
|
||||||
|
|
||||||
|
**Workflow Orchestration Service**:
|
||||||
|
- Event-driven processing
|
||||||
|
- State management
|
||||||
|
- Error handling and retry logic
|
||||||
|
- Progress tracking
|
||||||
|
|
||||||
|
### Event-Driven Architecture
|
||||||
|
|
||||||
|
**Core Events**:
|
||||||
|
```python
|
||||||
|
class AssessmentDiscoveredEvent(DomainEvent):
|
||||||
|
def __init__(self, assessment_id: str, assessment_type: str, source_url: str):
|
||||||
|
self.assessment_id = assessment_id
|
||||||
|
self.assessment_type = assessment_type
|
||||||
|
self.source_url = source_url
|
||||||
|
|
||||||
|
class MediaTranscriptionCompletedEvent(DomainEvent):
|
||||||
|
def __init__(self, content_id: str, transcription_text: str, confidence_score: float):
|
||||||
|
self.content_id = content_id
|
||||||
|
self.transcription_text = transcription_text
|
||||||
|
self.confidence_score = confidence_score
|
||||||
|
|
||||||
|
class QualityAssessmentCompletedEvent(DomainEvent):
|
||||||
|
def __init__(self, assessment_id: str, quality_scores: Dict[str, float]):
|
||||||
|
self.assessment_id = assessment_id
|
||||||
|
self.quality_scores = quality_scores
|
||||||
|
```
|
||||||
|
|
||||||
|
**Event Flow**:
|
||||||
|
1. Assessment page detected → Discovery service extracts data
|
||||||
|
2. Media files identified → Processing service downloads and transcribes
|
||||||
|
3. Transcription completed → Quality service analyzes responses
|
||||||
|
4. Quality assessment done → Report service generates assessor report
|
||||||
|
5. Process complete → Notification service alerts stakeholders
|
||||||
|
|
||||||
|
### Integration Patterns
|
||||||
|
|
||||||
|
**Anti-Corruption Layer for aXcelerate LMS**:
|
||||||
|
- Abstraction layer for external system dependencies
|
||||||
|
- Data mapping between external and internal models
|
||||||
|
- Error handling and resilience patterns
|
||||||
|
|
||||||
|
**Plugin Architecture for Extensibility**:
|
||||||
|
```python
|
||||||
|
class QualityAssessmentPlugin(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
async def assess_response_quality(self,
|
||||||
|
question: AssessmentQuestion,
|
||||||
|
response: StudentResponse) -> QualityScore:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Registry for dynamic plugin loading
|
||||||
|
class QualityAssessmentPluginRegistry:
|
||||||
|
def register_plugin(self, assessment_type: AssessmentType, plugin: QualityAssessmentPlugin):
|
||||||
|
self.plugins[assessment_type] = plugin
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Architecture
|
||||||
|
|
||||||
|
**Event Store Implementation**:
|
||||||
|
- Immutable event log for audit trail
|
||||||
|
- Event replay for system recovery
|
||||||
|
- Snapshots for performance optimization
|
||||||
|
|
||||||
|
**Read Model Projections**:
|
||||||
|
- Optimized views for reporting
|
||||||
|
- Real-time updates from event stream
|
||||||
|
- Multiple persistence strategies
|
||||||
|
|
||||||
|
**Caching Strategy**:
|
||||||
|
- Redis for application-level caching
|
||||||
|
- Transcription result caching (expensive operations)
|
||||||
|
- Assessment data caching for quick retrieval
|
||||||
|
|
||||||
|
### Security & Compliance
|
||||||
|
|
||||||
|
**Data Protection**:
|
||||||
|
- Encryption at rest and in transit
|
||||||
|
- PII data anonymization options
|
||||||
|
- Secure file storage with access controls
|
||||||
|
|
||||||
|
**Access Control**:
|
||||||
|
- Role-based permission system
|
||||||
|
- Assessment data access auditing
|
||||||
|
- Secure API authentication
|
||||||
|
|
||||||
|
**Compliance Features**:
|
||||||
|
- GDPR compliance for student data
|
||||||
|
- Educational data privacy regulations
|
||||||
|
- Audit trail for all system interactions
|
||||||
|
|
||||||
|
### Scalability & Performance
|
||||||
|
|
||||||
|
**Asynchronous Processing**:
|
||||||
|
- Concurrent media file processing
|
||||||
|
- Background task queues
|
||||||
|
- Non-blocking I/O operations
|
||||||
|
|
||||||
|
**Horizontal Scaling**:
|
||||||
|
- Stateless service design
|
||||||
|
- Load balancing capabilities
|
||||||
|
- Database connection pooling
|
||||||
|
|
||||||
|
**Performance Optimization**:
|
||||||
|
- Lazy loading of large datasets
|
||||||
|
- Streaming for large file processing
|
||||||
|
- Memory-efficient algorithms
|
||||||
|
|
||||||
|
## Implementation Roadmap
|
||||||
|
|
||||||
|
### Phase 1: Foundation & Core Architecture (Weeks 1-2)
|
||||||
|
**Objectives**: Establish solid architectural foundation
|
||||||
|
- Set up modern Python project structure with pyproject.toml
|
||||||
|
- Implement clean architecture layers (domain, application, infrastructure)
|
||||||
|
- Create core domain models (Assessment, Question, MediaContent)
|
||||||
|
- Set up event sourcing infrastructure
|
||||||
|
- Configure development environment with uv, ruff, mypy
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Project scaffolding with proper dependency management
|
||||||
|
- Core domain models with type safety
|
||||||
|
- Basic event store implementation
|
||||||
|
- Development workflow with pre-commit hooks
|
||||||
|
|
||||||
|
### Phase 2: Enhanced Media Processing (Weeks 3-4)
|
||||||
|
**Objectives**: Build robust media processing pipeline
|
||||||
|
- Refactor existing voice_to_text.py into async service architecture
|
||||||
|
- Implement browser automation for aXcelerate LMS scraping
|
||||||
|
- Create media download and storage system
|
||||||
|
- Add video processing capabilities (segmentation, compilation)
|
||||||
|
- Implement caching for expensive transcription operations
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Async Whisper transcription service
|
||||||
|
- Browser automation for assessment discovery
|
||||||
|
- Media file processing pipeline
|
||||||
|
- Video compilation with watermarks and titles
|
||||||
|
|
||||||
|
### Phase 3: Quality Assessment Engine (Weeks 5-6)
|
||||||
|
**Objectives**: Develop intelligent response analysis
|
||||||
|
- Implement multi-dimensional quality assessment algorithms
|
||||||
|
- Create plugin architecture for different assessment types
|
||||||
|
- Add semantic similarity scoring using sentence transformers
|
||||||
|
- Integrate with external learning resources and documentation
|
||||||
|
- Implement confidence scoring and uncertainty quantification
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Quality assessment plugin system
|
||||||
|
- Advanced scoring algorithms
|
||||||
|
- External resource integration
|
||||||
|
- Confidence and uncertainty metrics
|
||||||
|
|
||||||
|
### Phase 4: Assessment Discovery & Processing (Weeks 7-8)
|
||||||
|
**Objectives**: Complete end-to-end processing workflow
|
||||||
|
- Implement automatic assessment type identification
|
||||||
|
- Create structured data extraction from web pages
|
||||||
|
- Build workflow orchestration with event-driven architecture
|
||||||
|
- Add real-time processing status and notifications
|
||||||
|
- Implement error handling and retry mechanisms
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Complete assessment discovery service
|
||||||
|
- Workflow orchestration system
|
||||||
|
- Real-time status tracking
|
||||||
|
- Robust error handling
|
||||||
|
|
||||||
|
### Phase 5: Reporting & User Interface (Weeks 9-10)
|
||||||
|
**Objectives**: Provide assessor-friendly reporting and interfaces
|
||||||
|
- Create templated report generation (PDF, HTML)
|
||||||
|
- Develop FastAPI-based REST API endpoints
|
||||||
|
- Build assessor dashboard for review and analysis
|
||||||
|
- Implement batch processing for multiple assessments
|
||||||
|
- Add export capabilities for various formats
|
||||||
|
|
||||||
|
**Deliverables**:
|
||||||
|
- Comprehensive reporting system
|
||||||
|
- REST API for system integration
|
||||||
|
- Web-based assessor interface
|
||||||
|
- Batch processing capabilities
|
||||||
|
|
||||||
|
## Technology Stack Summary
|
||||||
|
|
||||||
|
### Backend Framework
|
||||||
|
- **FastAPI**: High-performance async web framework
|
||||||
|
- **Pydantic v2**: Data validation and serialization
|
||||||
|
- **SQLAlchemy 2.0**: Async ORM for database operations
|
||||||
|
|
||||||
|
### Database & Storage
|
||||||
|
- **PostgreSQL**: Primary transactional database
|
||||||
|
- **Redis**: Caching and task queue
|
||||||
|
- **File Storage**: Local filesystem with cloud storage options
|
||||||
|
|
||||||
|
### Processing & AI
|
||||||
|
- **OpenAI Whisper**: Audio transcription (existing integration)
|
||||||
|
- **Sentence Transformers**: Semantic similarity analysis
|
||||||
|
- **OpenCV/FFmpeg**: Video processing and manipulation
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
- **Docker**: Containerization for consistent deployments
|
||||||
|
- **Docker Compose**: Development environment orchestration
|
||||||
|
- **Celery**: Background task processing
|
||||||
|
- **Prometheus/Grafana**: Monitoring and metrics
|
||||||
|
|
||||||
|
### Development Tools
|
||||||
|
- **uv**: Fast Python package management
|
||||||
|
- **ruff**: Code linting and formatting
|
||||||
|
- **mypy**: Static type checking
|
||||||
|
- **pytest**: Testing framework with async support
|
||||||
|
|
||||||
|
## Migration Strategy
|
||||||
|
|
||||||
|
### Building on Existing Whisper Implementation
|
||||||
|
1. **Gradual Integration**: Wrap existing `voice_to_text.py` in new service architecture
|
||||||
|
2. **Backward Compatibility**: Maintain current interfaces while adding new capabilities
|
||||||
|
3. **Incremental Enhancement**: Add new features without disrupting existing workflow
|
||||||
|
4. **Data Preservation**: Ensure existing transcription data remains accessible
|
||||||
|
|
||||||
|
### Risk Mitigation
|
||||||
|
- Comprehensive testing at each phase
|
||||||
|
- Rollback procedures for each deployment
|
||||||
|
- Monitoring and alerting for system health
|
||||||
|
- Documentation for troubleshooting and maintenance
|
||||||
|
|
||||||
|
## Success Metrics
|
||||||
|
|
||||||
|
### Technical Metrics
|
||||||
|
- **Processing Speed**: Sub-2 minute processing for typical assessments
|
||||||
|
- **Accuracy**: >95% transcription accuracy for clear audio
|
||||||
|
- **Reliability**: >99.5% uptime for core services
|
||||||
|
- **Scalability**: Handle 100+ concurrent assessments
|
||||||
|
|
||||||
|
### Business Metrics
|
||||||
|
- **Assessor Efficiency**: 50% reduction in manual review time
|
||||||
|
- **Quality Consistency**: Standardized quality metrics across assessors
|
||||||
|
- **Error Reduction**: 80% reduction in assessment processing errors
|
||||||
|
- **User Satisfaction**: >90% assessor satisfaction with system usability
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
This architecture provides a comprehensive, scalable foundation for automated assessment processing. The modular design ensures maintainability and extensibility, while the event-driven architecture enables reliable, traceable processing workflows. Building on the existing Whisper implementation, this system will evolve into a powerful tool for educational assessment automation.
|
||||||
|
|
||||||
|
The phased implementation approach allows for iterative development and validation, ensuring each component works effectively before building upon it. The focus on modern Python practices, clean architecture, and robust engineering principles will result in a system that can grow and adapt to future requirements while maintaining high performance and reliability.
|
||||||
@ -5,3 +5,8 @@ tqdm
|
|||||||
more-itertools
|
more-itertools
|
||||||
tiktoken
|
tiktoken
|
||||||
triton>=2.0.0;platform_machine=="x86_64" and sys_platform=="linux" or sys_platform=="linux2"
|
triton>=2.0.0;platform_machine=="x86_64" and sys_platform=="linux" or sys_platform=="linux2"
|
||||||
|
pyperclip
|
||||||
|
sounddevice
|
||||||
|
pynput
|
||||||
|
pystray
|
||||||
|
pillow
|
||||||
|
|||||||
81
setup.bat
Normal file
81
setup.bat
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
@echo off
|
||||||
|
title Voice to Text Converter - Setup
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
echo ========================================
|
||||||
|
echo Voice to Text Converter - Setup
|
||||||
|
echo ========================================
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Check if Python is available
|
||||||
|
echo [1/4] Checking Python installation...
|
||||||
|
python --version >nul 2>&1
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] Python is not installed or not in PATH
|
||||||
|
echo.
|
||||||
|
echo Please install Python 3.8+ from: https://python.org
|
||||||
|
echo Make sure to check "Add Python to PATH" during installation
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
python --version
|
||||||
|
echo [OK] Python found!
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Check if requirements.txt exists
|
||||||
|
echo [2/4] Checking requirements file...
|
||||||
|
if not exist "requirements.txt" (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] requirements.txt not found
|
||||||
|
echo Make sure you're running this from the correct directory
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
echo [OK] Requirements file found!
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Install dependencies
|
||||||
|
echo [3/4] Installing dependencies...
|
||||||
|
echo This may take a few minutes...
|
||||||
|
echo.
|
||||||
|
pip install -r requirements.txt
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] Failed to install dependencies
|
||||||
|
echo Please check your internet connection and try again
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
echo.
|
||||||
|
echo [OK] Dependencies installed successfully!
|
||||||
|
echo.
|
||||||
|
|
||||||
|
REM Test import
|
||||||
|
echo [4/4] Testing installation...
|
||||||
|
python -c "import voice_to_text; print('[OK] Voice-to-text module loads successfully!')" 2>nul
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo [WARNING] Installation completed but module test failed
|
||||||
|
echo This might still work, but check for any error messages above
|
||||||
|
echo.
|
||||||
|
) else (
|
||||||
|
echo [OK] Installation test passed!
|
||||||
|
echo.
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ========================================
|
||||||
|
echo Setup Complete!
|
||||||
|
echo ========================================
|
||||||
|
echo.
|
||||||
|
echo You can now use:
|
||||||
|
echo - voice_to_text_terminal.bat (for terminal mode)
|
||||||
|
echo - voice_to_text_gui.bat (for GUI mode)
|
||||||
|
echo.
|
||||||
|
echo Note: First run will download Whisper models (~150MB)
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
144
transcribe_assessment.py
Normal file
144
transcribe_assessment.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Assessment Audio Transcription and Analysis Tool
|
||||||
|
Transcribes MOV files and compares to assessment questions
|
||||||
|
"""
|
||||||
|
|
||||||
|
import whisper
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def transcribe_audio_file(file_path, model_name="base"):
|
||||||
|
"""Transcribe an audio file using Whisper"""
|
||||||
|
print(f"Loading Whisper model: {model_name}")
|
||||||
|
model = whisper.load_model(model_name)
|
||||||
|
|
||||||
|
print(f"Transcribing: {file_path}")
|
||||||
|
result = model.transcribe(str(file_path))
|
||||||
|
|
||||||
|
return {
|
||||||
|
"text": result["text"].strip(),
|
||||||
|
"language": result["language"],
|
||||||
|
"segments": result["segments"]
|
||||||
|
}
|
||||||
|
|
||||||
|
def analyze_response(question, transcribed_text, written_summary):
|
||||||
|
"""Analyze the quality of the student's response"""
|
||||||
|
|
||||||
|
analysis = {
|
||||||
|
"question": question,
|
||||||
|
"transcribed_answer": transcribed_text,
|
||||||
|
"written_summary": written_summary,
|
||||||
|
"assessment": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Basic analysis criteria
|
||||||
|
word_count = len(transcribed_text.split())
|
||||||
|
analysis["assessment"]["word_count"] = word_count
|
||||||
|
analysis["assessment"]["has_substantial_content"] = word_count >= 10
|
||||||
|
|
||||||
|
# Check if response addresses the question
|
||||||
|
question_keywords = extract_keywords(question)
|
||||||
|
response_lower = transcribed_text.lower()
|
||||||
|
keyword_matches = sum(1 for keyword in question_keywords if keyword in response_lower)
|
||||||
|
analysis["assessment"]["keyword_relevance"] = keyword_matches / len(question_keywords) if question_keywords else 0
|
||||||
|
|
||||||
|
# Compare transcription to written summary
|
||||||
|
if written_summary:
|
||||||
|
similarity_score = basic_similarity(transcribed_text.lower(), written_summary.lower())
|
||||||
|
analysis["assessment"]["transcription_summary_match"] = similarity_score
|
||||||
|
|
||||||
|
return analysis
|
||||||
|
|
||||||
|
def extract_keywords(question):
|
||||||
|
"""Extract key terms from the question"""
|
||||||
|
# Simple keyword extraction - remove common words
|
||||||
|
stop_words = {"what", "is", "the", "of", "for", "a", "an", "in", "on", "at", "to", "where", "how", "why"}
|
||||||
|
words = question.lower().replace("?", "").split()
|
||||||
|
return [word for word in words if word not in stop_words and len(word) > 2]
|
||||||
|
|
||||||
|
def basic_similarity(text1, text2):
|
||||||
|
"""Basic similarity score between two texts"""
|
||||||
|
words1 = set(text1.split())
|
||||||
|
words2 = set(text2.split())
|
||||||
|
|
||||||
|
if not words1 and not words2:
|
||||||
|
return 1.0
|
||||||
|
if not words1 or not words2:
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
intersection = words1.intersection(words2)
|
||||||
|
union = words1.union(words2)
|
||||||
|
|
||||||
|
return len(intersection) / len(union)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main transcription and analysis workflow"""
|
||||||
|
|
||||||
|
# Assessment questions and expected files
|
||||||
|
assessment_data = {
|
||||||
|
"Q1": {
|
||||||
|
"question": "What is the purpose of determining and documenting requirements for a cabinet installation?",
|
||||||
|
"file": "IMG_1060.mov",
|
||||||
|
"written_summary": "To have a better understanding of the project for all persons involved and plan in advance for any difficulties and refer to documents as a guide for future projects."
|
||||||
|
},
|
||||||
|
"Q2": {
|
||||||
|
"question": "Where on an architectural drawing is the materials list for the project?",
|
||||||
|
"file": "77914809189__571E73A4-D2E8-4B00-934C-5B2E54DE47A4.MOV",
|
||||||
|
"written_summary": "It's part of the title block or in a separate block usually called the Schedule."
|
||||||
|
},
|
||||||
|
"Q3": {
|
||||||
|
"question": "What information is found in the appliance manuals?",
|
||||||
|
"file": "IMG_1062.mov",
|
||||||
|
"written_summary": "Fitting instructions and requirements"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
results = {}
|
||||||
|
|
||||||
|
for question_id, data in assessment_data.items():
|
||||||
|
file_path = Path(data["file"])
|
||||||
|
|
||||||
|
if file_path.exists():
|
||||||
|
print(f"\n=== Processing {question_id} ===")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Transcribe the audio
|
||||||
|
transcription = transcribe_audio_file(file_path)
|
||||||
|
|
||||||
|
# Analyze the response
|
||||||
|
analysis = analyze_response(
|
||||||
|
data["question"],
|
||||||
|
transcription["text"],
|
||||||
|
data["written_summary"]
|
||||||
|
)
|
||||||
|
|
||||||
|
analysis["transcription_details"] = transcription
|
||||||
|
results[question_id] = analysis
|
||||||
|
|
||||||
|
print(f"Question: {data['question']}")
|
||||||
|
print(f"Transcribed Answer: {transcription['text']}")
|
||||||
|
print(f"Written Summary: {data['written_summary']}")
|
||||||
|
print(f"Word Count: {analysis['assessment']['word_count']}")
|
||||||
|
print(f"Keyword Relevance: {analysis['assessment']['keyword_relevance']:.2f}")
|
||||||
|
|
||||||
|
if 'transcription_summary_match' in analysis['assessment']:
|
||||||
|
print(f"Transcription-Summary Match: {analysis['assessment']['transcription_summary_match']:.2f}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing {question_id}: {e}")
|
||||||
|
results[question_id] = {"error": str(e)}
|
||||||
|
else:
|
||||||
|
print(f"File not found: {file_path}")
|
||||||
|
results[question_id] = {"error": f"File not found: {file_path}"}
|
||||||
|
|
||||||
|
# Save results
|
||||||
|
with open("assessment_analysis.json", "w") as f:
|
||||||
|
json.dump(results, f, indent=2)
|
||||||
|
|
||||||
|
print(f"\nResults saved to assessment_analysis.json")
|
||||||
|
return results
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
10
transcripts/transcription_20250916_073921.txt
Normal file
10
transcripts/transcription_20250916_073921.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 07:39:21
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Testing it out let's see how it goes I've recorded this with a microphone.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Testing it out let's see how it goes I've recorded this with a microphone.
|
||||||
10
transcripts/transcription_20250916_074026.txt
Normal file
10
transcripts/transcription_20250916_074026.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 07:40:26
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Testing out check the directory downloads for any new files.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Testing out check the @dir downloads/ for any new files.
|
||||||
10
transcripts/transcription_20250916_080226.txt
Normal file
10
transcripts/transcription_20250916_080226.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 08:02:26
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Testing the record function to see how well it works.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Testing the record `to()` function see how well it works.
|
||||||
9
transcripts/transcription_20250916_080258.txt
Normal file
9
transcripts/transcription_20250916_080258.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Transcription - 2025-09-16 08:02:58
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
10
transcripts/transcription_20250916_090049.txt
Normal file
10
transcripts/transcription_20250916_090049.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 09:00:49
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Testing how effective the voice recorder is.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Testing how effective the voice recorder is.
|
||||||
10
transcripts/transcription_20250916_090157.txt
Normal file
10
transcripts/transcription_20250916_090157.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 09:01:57
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
The error user warning FP16 is not supported on CPU using FP32 instead warnings. Not one, FP16 is not supported on CPU using FP32 instead.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
The error user warning FP16 is not supported on CPU using FP32 instead warnings. Not one, FP16 is not supported on CPU using FP32 instead.
|
||||||
10
transcripts/transcription_20250916_090409.txt
Normal file
10
transcripts/transcription_20250916_090409.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 09:04:09
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
I would like to package the app for windows, suggest some solutions.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
I would like to package the app for windows, suggest some solutions.
|
||||||
10
transcripts/transcription_20250916_095710.txt
Normal file
10
transcripts/transcription_20250916_095710.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 09:57:10
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
The terminal doesn't close after the app starts but now if I close the terminal the Python app will stay open.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
The terminal doesn't close after the app starts but now if I close the terminal the Python app will stay open.
|
||||||
10
transcripts/transcription_20250916_095712.txt
Normal file
10
transcripts/transcription_20250916_095712.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 09:57:12
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
The terminal doesn't close after the app starts, but now if I close the terminal, the Python app will stay open.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
The terminal doesn't close after the app starts, but now if I close the terminal, the Python app will stay open.
|
||||||
10
transcripts/transcription_20250916_100021.txt
Normal file
10
transcripts/transcription_20250916_100021.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:00:21
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_100050.txt
Normal file
10
transcripts/transcription_20250916_100050.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:00:50
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
9 ok Aiaa 1 E Ren hear 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
9 ok Aiaa 1 E Ren hear 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_100226.txt
Normal file
10
transcripts/transcription_20250916_100226.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:26
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
I would like to install MPC browser in Claude code.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
I would like to install MPC browser in Claude code.
|
||||||
10
transcripts/transcription_20250916_100229.txt
Normal file
10
transcripts/transcription_20250916_100229.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:29
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
I would like to install NPC browser in Claude code.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
I would like to install NPC browser in Claude code.
|
||||||
10
transcripts/transcription_20250916_100231.txt
Normal file
10
transcripts/transcription_20250916_100231.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:31
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
I would like to install MPC browser in Claude code.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
I would like to install MPC browser in Claude code.
|
||||||
10
transcripts/transcription_20250916_100232.txt
Normal file
10
transcripts/transcription_20250916_100232.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:32
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
10
transcripts/transcription_20250916_100233.txt
Normal file
10
transcripts/transcription_20250916_100233.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:33
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
I would like to install NPC browser in Claude code.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
I would like to install NPC browser in Claude code.
|
||||||
10
transcripts/transcription_20250916_100235.txt
Normal file
10
transcripts/transcription_20250916_100235.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:35
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
|
||||||
10
transcripts/transcription_20250916_100242.txt
Normal file
10
transcripts/transcription_20250916_100242.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:02:42
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
I would like to install MPC browser in code. Claude code.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
I would like to install MPC browser in code. Claude code.
|
||||||
10
transcripts/transcription_20250916_100426.txt
Normal file
10
transcripts/transcription_20250916_100426.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:04:26
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Proceed with method 1.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Proceed with `1()` method.
|
||||||
10
transcripts/transcription_20250916_100431.txt
Normal file
10
transcripts/transcription_20250916_100431.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:04:31
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_100433.txt
Normal file
10
transcripts/transcription_20250916_100433.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:04:33
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Proceed with method one.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Proceed with `one()` method.
|
||||||
10
transcripts/transcription_20250916_100436.txt
Normal file
10
transcripts/transcription_20250916_100436.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:04:36
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_100655.txt
Normal file
10
transcripts/transcription_20250916_100655.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:06:55
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5% 2.5%.
|
||||||
10
transcripts/transcription_20250916_100704.txt
Normal file
10
transcripts/transcription_20250916_100704.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:04
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
30g dorud Mex 1g
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
30g dorud Mex 1g.
|
||||||
10
transcripts/transcription_20250916_100706.txt
Normal file
10
transcripts/transcription_20250916_100706.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:06
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5kg 1.5kg 1.5kg 1.5kg 1.5kg 1kg 1kg
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5kg 1.5kg 1.5kg 1.5kg 1.5kg 1kg 1kg.
|
||||||
10
transcripts/transcription_20250916_100710.txt
Normal file
10
transcripts/transcription_20250916_100710.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:10
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
In the currently open browser, find the button called add note and press it.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
In the currently open browser, find the button called add note and press it.
|
||||||
10
transcripts/transcription_20250916_100713.txt
Normal file
10
transcripts/transcription_20250916_100713.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:13
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
In the currently open browser, find the button called add note and press it.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
In the currently open browser, find the button called add note and press it.
|
||||||
10
transcripts/transcription_20250916_100717.txt
Normal file
10
transcripts/transcription_20250916_100717.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:17
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
In the currently open browser, find the button called add note and press it.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
In the currently open browser, find the button called add note and press it.
|
||||||
10
transcripts/transcription_20250916_100722.txt
Normal file
10
transcripts/transcription_20250916_100722.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:22
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_100724.txt
Normal file
10
transcripts/transcription_20250916_100724.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:07:24
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
9
transcripts/transcription_20250916_101057.txt
Normal file
9
transcripts/transcription_20250916_101057.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Transcription - 2025-09-16 10:10:57
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
9
transcripts/transcription_20250916_101059.txt
Normal file
9
transcripts/transcription_20250916_101059.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Transcription - 2025-09-16 10:10:59
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
9
transcripts/transcription_20250916_101101.txt
Normal file
9
transcripts/transcription_20250916_101101.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:01
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
9
transcripts/transcription_20250916_101103.txt
Normal file
9
transcripts/transcription_20250916_101103.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:03
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
10
transcripts/transcription_20250916_101110.txt
Normal file
10
transcripts/transcription_20250916_101110.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:10
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_101111.txt
Normal file
10
transcripts/transcription_20250916_101111.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:11
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Use browser NPC on the current open page in Chrome. Press the add note button.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Use browser NPC on the current open page in Chrome. Press the add note button.
|
||||||
10
transcripts/transcription_20250916_101116.txt
Normal file
10
transcripts/transcription_20250916_101116.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:16
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5% 1.5%.
|
||||||
10
transcripts/transcription_20250916_101121.txt
Normal file
10
transcripts/transcription_20250916_101121.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:21
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Press the Add Note button in the currently open web page using browser MPC.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Press the Add Note button in the currently open web page using browser MPC.
|
||||||
10
transcripts/transcription_20250916_101152.txt
Normal file
10
transcripts/transcription_20250916_101152.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:52
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Press the add note button in the currently open web page using browser MPC.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Press the add note button in the currently open web page using browser MPC.
|
||||||
10
transcripts/transcription_20250916_101153.txt
Normal file
10
transcripts/transcription_20250916_101153.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:11:53
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Press the Add Note button in the currently open web page using browser MPC.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Press the Add Note button in the currently open web page using browser MPC.
|
||||||
10
transcripts/transcription_20250916_101528.txt
Normal file
10
transcripts/transcription_20250916_101528.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:15:28
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Take an HTML snapshot of the currently open web page and create a report showing headings that have item in a number or a question and a number, links to downloads of media files and responses to questions.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Take an HTML snapshot of the currently open web page and create a report showing headings that have item in a number or a question and a number, links to downloads of media files and responses to questions.
|
||||||
10
transcripts/transcription_20250916_101735.txt
Normal file
10
transcripts/transcription_20250916_101735.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:17:35
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Use whisper to down
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Use whisper to down.
|
||||||
10
transcripts/transcription_20250916_101809.txt
Normal file
10
transcripts/transcription_20250916_101809.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Transcription - 2025-09-16 10:18:09
|
||||||
|
============================================================
|
||||||
|
RAW TRANSCRIPTION:
|
||||||
|
============================================================
|
||||||
|
Download the Move.mov files and use Whisper to convert speech to text for each movie file. Compare the text to the question and respond whether the student's answer is a good answer.
|
||||||
|
|
||||||
|
============================================================
|
||||||
|
PROCESSED PROMPT:
|
||||||
|
============================================================
|
||||||
|
Download the Move.mov files and use Whisper to convert speech to text for each movie file. Compare the text to the question and respond whether the student's answer is a good answer.
|
||||||
776
voice_to_text.py
Normal file
776
voice_to_text.py
Normal file
@ -0,0 +1,776 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Voice Recording and Transcription Script
|
||||||
|
Records audio from microphone and converts it to text using OpenAI Whisper
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sounddevice as sd
|
||||||
|
import numpy as np
|
||||||
|
import whisper
|
||||||
|
import tempfile
|
||||||
|
import wave
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import pyperclip
|
||||||
|
import sys
|
||||||
|
import tkinter as tk
|
||||||
|
from tkinter import ttk, scrolledtext, messagebox
|
||||||
|
import threading
|
||||||
|
import json
|
||||||
|
import warnings
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
from pynput import keyboard
|
||||||
|
import pystray
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
|
# Suppress common PyTorch/Whisper warnings
|
||||||
|
warnings.filterwarnings("ignore", message="FP16 is not supported on CPU")
|
||||||
|
warnings.filterwarnings("ignore", message=".*FP16.*")
|
||||||
|
warnings.filterwarnings("ignore", category=UserWarning, module="whisper")
|
||||||
|
|
||||||
|
# Set environment variable to reduce PyTorch verbosity
|
||||||
|
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
||||||
|
|
||||||
|
class PromptProcessor:
|
||||||
|
"""Processes transcribed text to create better Claude Code prompts"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.patterns = [
|
||||||
|
# Agent references
|
||||||
|
(r'\buse agent ([\w-]+)\b', r'@agent \1'),
|
||||||
|
(r'\blaunch agent ([\w-]+(?:\s+[\w-]+)*)\b', lambda m: f"@agent {m.group(1).replace(' ', '-')}"),
|
||||||
|
(r'\bcall agent ([\w-]+(?:\s+[\w-]+)*)\b', lambda m: f"@agent {m.group(1).replace(' ', '-')}"),
|
||||||
|
|
||||||
|
# Tool references
|
||||||
|
(r'\brun tool (\w+)\b', r'@tool \1'),
|
||||||
|
(r'\bcall the (\w+) tool\b', r'@tool \1'),
|
||||||
|
(r'\buse the (\w+) tool\b', r'@tool \1'),
|
||||||
|
|
||||||
|
# Directory references
|
||||||
|
(r'\bdirectory ([\w/\\.-]+)\b', r'@dir \1/'),
|
||||||
|
(r'\bfolder ([\w/\\.-]+)\b', r'@dir \1/'),
|
||||||
|
(r'\bthe ([\w.-]+) directory\b', r'@dir \1/'),
|
||||||
|
|
||||||
|
# File references
|
||||||
|
(r'\bfile ([\w/\\.-]+\.[\w]+)\b', r'@file \1'),
|
||||||
|
(r'\bthe ([\w.-]+\.[\w]+) file\b', r'@file \1'),
|
||||||
|
(r'\breadme file\b', '@file README.md'),
|
||||||
|
(r'\bpackage json\b', '@file package.json'),
|
||||||
|
|
||||||
|
# Code elements
|
||||||
|
(r'\bfunction ([\w_]+)\b', r'`\1()` function'),
|
||||||
|
(r'\bclass ([\w_]+)\b', r'`\1` class'),
|
||||||
|
(r'\bvariable ([\w_]+)\b', r'`\1` variable'),
|
||||||
|
(r'\bmethod ([\w_]+)\b', r'`\1()` method'),
|
||||||
|
|
||||||
|
# Task management
|
||||||
|
(r'\badd to todo\b', 'add to todo:'),
|
||||||
|
(r'\bnew task\b', 'new todo:'),
|
||||||
|
(r'\bmark complete\b', 'mark todo complete'),
|
||||||
|
(r'\bmark done\b', 'mark todo complete'),
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
(r'\brun tests\b', 'run tests'),
|
||||||
|
(r'\bcommit changes\b', 'commit changes'),
|
||||||
|
(r'\bcreate pull request\b', 'create PR'),
|
||||||
|
(r'\binstall dependencies\b', 'install dependencies'),
|
||||||
|
]
|
||||||
|
|
||||||
|
def process(self, text):
|
||||||
|
"""Process raw transcription into a Claude Code prompt"""
|
||||||
|
processed = text.strip()
|
||||||
|
|
||||||
|
# Apply pattern replacements
|
||||||
|
for pattern, replacement in self.patterns:
|
||||||
|
if callable(replacement):
|
||||||
|
processed = re.sub(pattern, replacement, processed, flags=re.IGNORECASE)
|
||||||
|
else:
|
||||||
|
processed = re.sub(pattern, replacement, processed, flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
# Capitalize first letter and ensure proper punctuation
|
||||||
|
if processed:
|
||||||
|
processed = processed[0].upper() + processed[1:] if len(processed) > 1 else processed.upper()
|
||||||
|
if not processed.endswith(('.', '!', '?', ':')):
|
||||||
|
processed += '.'
|
||||||
|
|
||||||
|
return processed
|
||||||
|
|
||||||
|
class SettingsManager:
|
||||||
|
"""Manages application settings with JSON persistence"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.settings_file = Path('voice_to_text_settings.json')
|
||||||
|
self.default_settings = {
|
||||||
|
'hotkey': 'f1',
|
||||||
|
'always_on_top': False,
|
||||||
|
'minimize_to_tray': True,
|
||||||
|
'whisper_model': 'base',
|
||||||
|
'window_geometry': '600x500',
|
||||||
|
'auto_copy_clipboard': True
|
||||||
|
}
|
||||||
|
self.settings = self.load_settings()
|
||||||
|
|
||||||
|
def load_settings(self):
|
||||||
|
"""Load settings from JSON file or create defaults"""
|
||||||
|
try:
|
||||||
|
if self.settings_file.exists():
|
||||||
|
with open(self.settings_file, 'r') as f:
|
||||||
|
settings = json.load(f)
|
||||||
|
# Merge with defaults to handle new settings
|
||||||
|
merged = self.default_settings.copy()
|
||||||
|
merged.update(settings)
|
||||||
|
return merged
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading settings: {e}")
|
||||||
|
return self.default_settings.copy()
|
||||||
|
|
||||||
|
def save_settings(self):
|
||||||
|
"""Save current settings to JSON file"""
|
||||||
|
try:
|
||||||
|
with open(self.settings_file, 'w') as f:
|
||||||
|
json.dump(self.settings, f, indent=2)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error saving settings: {e}")
|
||||||
|
|
||||||
|
def get(self, key, default=None):
|
||||||
|
"""Get a setting value"""
|
||||||
|
return self.settings.get(key, default)
|
||||||
|
|
||||||
|
def set(self, key, value):
|
||||||
|
"""Set a setting value and save"""
|
||||||
|
self.settings[key] = value
|
||||||
|
self.save_settings()
|
||||||
|
|
||||||
|
class VoiceRecorder:
|
||||||
|
def __init__(self, sample_rate=16000, channels=1, settings_manager=None):
|
||||||
|
self.sample_rate = sample_rate
|
||||||
|
self.channels = channels
|
||||||
|
self.recording = False
|
||||||
|
self.audio_data = []
|
||||||
|
self.processor = PromptProcessor()
|
||||||
|
self.settings = settings_manager or SettingsManager()
|
||||||
|
|
||||||
|
# Ensure transcripts directory exists
|
||||||
|
self.transcripts_dir = Path('transcripts')
|
||||||
|
self.transcripts_dir.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
def record_audio(self, duration=None):
|
||||||
|
"""
|
||||||
|
Record audio from microphone
|
||||||
|
Args:
|
||||||
|
duration: Recording duration in seconds. If None, records until Enter is pressed
|
||||||
|
"""
|
||||||
|
print("Loading Whisper model...")
|
||||||
|
model = whisper.load_model("base")
|
||||||
|
|
||||||
|
if duration:
|
||||||
|
print(f"Recording for {duration} seconds...")
|
||||||
|
audio = sd.rec(int(duration * self.sample_rate),
|
||||||
|
samplerate=self.sample_rate,
|
||||||
|
channels=self.channels,
|
||||||
|
dtype=np.float32)
|
||||||
|
sd.wait()
|
||||||
|
print("Recording complete!")
|
||||||
|
else:
|
||||||
|
print("Recording... Press Enter to stop.")
|
||||||
|
self.recording = True
|
||||||
|
self.audio_data = []
|
||||||
|
|
||||||
|
def callback(indata, frames, time, status):
|
||||||
|
if self.recording:
|
||||||
|
self.audio_data.append(indata.copy())
|
||||||
|
|
||||||
|
with sd.InputStream(callback=callback,
|
||||||
|
samplerate=self.sample_rate,
|
||||||
|
channels=self.channels,
|
||||||
|
dtype=np.float32):
|
||||||
|
input() # Wait for Enter key
|
||||||
|
self.recording = False
|
||||||
|
|
||||||
|
if self.audio_data:
|
||||||
|
audio = np.concatenate(self.audio_data, axis=0)
|
||||||
|
else:
|
||||||
|
print("No audio recorded.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Save to temporary file
|
||||||
|
temp_file = self._save_to_temp_file(audio)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Transcribe with Whisper
|
||||||
|
print("Transcribing...")
|
||||||
|
result = model.transcribe(temp_file)
|
||||||
|
|
||||||
|
# Process the transcription
|
||||||
|
raw_text = result["text"]
|
||||||
|
processed_text = self.processor.process(raw_text)
|
||||||
|
|
||||||
|
# Display results
|
||||||
|
print("\n" + "="*50)
|
||||||
|
print("RAW TRANSCRIPTION:")
|
||||||
|
print("="*50)
|
||||||
|
print(raw_text)
|
||||||
|
print("\n" + "="*50)
|
||||||
|
print("PROCESSED PROMPT:")
|
||||||
|
print("="*50)
|
||||||
|
print(processed_text)
|
||||||
|
print("="*50)
|
||||||
|
|
||||||
|
# Copy processed text to clipboard
|
||||||
|
try:
|
||||||
|
pyperclip.copy(processed_text)
|
||||||
|
print("\n✓ Processed prompt copied to clipboard!")
|
||||||
|
print("You can now paste it directly into Claude Code.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n⚠ Could not copy to clipboard: {e}")
|
||||||
|
print("Please copy the processed text manually.")
|
||||||
|
|
||||||
|
# Save to file in transcripts directory
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
output_file = self.transcripts_dir / f"transcription_{timestamp}.txt"
|
||||||
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(f"Transcription - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write("RAW TRANSCRIPTION:\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write(raw_text + "\n\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write("PROCESSED PROMPT:\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write(processed_text)
|
||||||
|
|
||||||
|
print(f"\nTranscription saved to: {output_file}")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Clean up temporary file
|
||||||
|
os.unlink(temp_file)
|
||||||
|
|
||||||
|
def _save_to_temp_file(self, audio_data):
|
||||||
|
"""Save audio data to temporary WAV file"""
|
||||||
|
temp_file = tempfile.mktemp(suffix=".wav")
|
||||||
|
|
||||||
|
with wave.open(temp_file, 'wb') as wf:
|
||||||
|
wf.setnchannels(self.channels)
|
||||||
|
wf.setsampwidth(2) # 16-bit
|
||||||
|
wf.setframerate(self.sample_rate)
|
||||||
|
|
||||||
|
# Convert float32 to int16
|
||||||
|
audio_int16 = (audio_data * 32767).astype(np.int16)
|
||||||
|
wf.writeframes(audio_int16.tobytes())
|
||||||
|
|
||||||
|
return temp_file
|
||||||
|
|
||||||
|
class SettingsDialog:
|
||||||
|
"""Settings dialog for configuring the voice recorder"""
|
||||||
|
|
||||||
|
def __init__(self, parent, settings_manager, apply_callback):
|
||||||
|
self.settings = settings_manager
|
||||||
|
self.apply_callback = apply_callback
|
||||||
|
|
||||||
|
# Create dialog window
|
||||||
|
self.dialog = tk.Toplevel(parent)
|
||||||
|
self.dialog.title("Settings")
|
||||||
|
self.dialog.geometry("400x300")
|
||||||
|
self.dialog.resizable(False, False)
|
||||||
|
self.dialog.transient(parent)
|
||||||
|
self.dialog.grab_set()
|
||||||
|
|
||||||
|
# Center the dialog
|
||||||
|
self.dialog.update_idletasks()
|
||||||
|
x = (self.dialog.winfo_screenwidth() // 2) - (400 // 2)
|
||||||
|
y = (self.dialog.winfo_screenheight() // 2) - (300 // 2)
|
||||||
|
self.dialog.geometry(f"400x300+{x}+{y}")
|
||||||
|
|
||||||
|
self.create_widgets()
|
||||||
|
|
||||||
|
def create_widgets(self):
|
||||||
|
"""Create the settings widgets"""
|
||||||
|
main_frame = ttk.Frame(self.dialog, padding="20")
|
||||||
|
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
# Hotkey setting
|
||||||
|
ttk.Label(main_frame, text="Global Hotkey:", font=('Arial', 10, 'bold')).pack(anchor=tk.W, pady=(0, 5))
|
||||||
|
hotkey_frame = ttk.Frame(main_frame)
|
||||||
|
hotkey_frame.pack(fill=tk.X, pady=(0, 15))
|
||||||
|
|
||||||
|
self.hotkey_var = tk.StringVar(value=self.settings.get('hotkey', 'f1'))
|
||||||
|
hotkey_combo = ttk.Combobox(hotkey_frame, textvariable=self.hotkey_var,
|
||||||
|
values=['f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'],
|
||||||
|
state="readonly", width=10)
|
||||||
|
hotkey_combo.pack(side=tk.LEFT)
|
||||||
|
ttk.Label(hotkey_frame, text="(Press this key anywhere to start/stop recording)").pack(side=tk.LEFT, padx=(10, 0))
|
||||||
|
|
||||||
|
# Whisper model setting
|
||||||
|
ttk.Label(main_frame, text="Whisper Model:", font=('Arial', 10, 'bold')).pack(anchor=tk.W, pady=(0, 5))
|
||||||
|
model_frame = ttk.Frame(main_frame)
|
||||||
|
model_frame.pack(fill=tk.X, pady=(0, 15))
|
||||||
|
|
||||||
|
self.model_var = tk.StringVar(value=self.settings.get('whisper_model', 'base'))
|
||||||
|
model_combo = ttk.Combobox(model_frame, textvariable=self.model_var,
|
||||||
|
values=['tiny', 'base', 'small', 'medium', 'large', 'turbo'],
|
||||||
|
state="readonly", width=10)
|
||||||
|
model_combo.pack(side=tk.LEFT)
|
||||||
|
ttk.Label(model_frame, text="(tiny=fastest, large=most accurate)").pack(side=tk.LEFT, padx=(10, 0))
|
||||||
|
|
||||||
|
# Boolean settings
|
||||||
|
ttk.Label(main_frame, text="Options:", font=('Arial', 10, 'bold')).pack(anchor=tk.W, pady=(15, 5))
|
||||||
|
|
||||||
|
self.always_on_top_var = tk.BooleanVar(value=self.settings.get('always_on_top', False))
|
||||||
|
ttk.Checkbutton(main_frame, text="Keep window always on top",
|
||||||
|
variable=self.always_on_top_var).pack(anchor=tk.W, pady=2)
|
||||||
|
|
||||||
|
self.minimize_to_tray_var = tk.BooleanVar(value=self.settings.get('minimize_to_tray', True))
|
||||||
|
ttk.Checkbutton(main_frame, text="Minimize to system tray when closed",
|
||||||
|
variable=self.minimize_to_tray_var).pack(anchor=tk.W, pady=2)
|
||||||
|
|
||||||
|
self.auto_copy_var = tk.BooleanVar(value=self.settings.get('auto_copy_clipboard', True))
|
||||||
|
ttk.Checkbutton(main_frame, text="Automatically copy processed text to clipboard",
|
||||||
|
variable=self.auto_copy_var).pack(anchor=tk.W, pady=2)
|
||||||
|
|
||||||
|
# Buttons
|
||||||
|
button_frame = ttk.Frame(main_frame)
|
||||||
|
button_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=(20, 0))
|
||||||
|
|
||||||
|
ttk.Button(button_frame, text="Cancel", command=self.cancel).pack(side=tk.RIGHT, padx=(5, 0))
|
||||||
|
ttk.Button(button_frame, text="Apply", command=self.apply).pack(side=tk.RIGHT)
|
||||||
|
|
||||||
|
def apply(self):
|
||||||
|
"""Apply the settings"""
|
||||||
|
# Update settings
|
||||||
|
self.settings.set('hotkey', self.hotkey_var.get())
|
||||||
|
self.settings.set('whisper_model', self.model_var.get())
|
||||||
|
self.settings.set('always_on_top', self.always_on_top_var.get())
|
||||||
|
self.settings.set('minimize_to_tray', self.minimize_to_tray_var.get())
|
||||||
|
self.settings.set('auto_copy_clipboard', self.auto_copy_var.get())
|
||||||
|
|
||||||
|
# Call the apply callback
|
||||||
|
if self.apply_callback:
|
||||||
|
self.apply_callback()
|
||||||
|
|
||||||
|
self.dialog.destroy()
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
"""Cancel the dialog"""
|
||||||
|
self.dialog.destroy()
|
||||||
|
|
||||||
|
class VoiceRecorderGUI:
|
||||||
|
"""GUI version of the voice recorder with hotkey support"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.settings = SettingsManager()
|
||||||
|
self.recorder = VoiceRecorder(settings_manager=self.settings)
|
||||||
|
self.is_recording = False
|
||||||
|
self.hotkey_listener = None
|
||||||
|
self.tray_icon = None
|
||||||
|
self.is_closing = False
|
||||||
|
|
||||||
|
# Create main window
|
||||||
|
self.root = tk.Tk()
|
||||||
|
self.root.title("Voice to Text Converter")
|
||||||
|
geometry = self.settings.get('window_geometry', '600x500')
|
||||||
|
self.root.geometry(geometry)
|
||||||
|
self.root.resizable(True, True)
|
||||||
|
|
||||||
|
# Set always on top if enabled
|
||||||
|
if self.settings.get('always_on_top', False):
|
||||||
|
self.root.wm_attributes('-topmost', True)
|
||||||
|
|
||||||
|
# Set up tray first (before UI setup)
|
||||||
|
if self.settings.get('minimize_to_tray', True):
|
||||||
|
self.setup_tray()
|
||||||
|
|
||||||
|
self.setup_ui()
|
||||||
|
self.setup_hotkey()
|
||||||
|
|
||||||
|
def setup_ui(self):
|
||||||
|
"""Set up the GUI elements"""
|
||||||
|
# Main frame
|
||||||
|
main_frame = ttk.Frame(self.root, padding="10")
|
||||||
|
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||||
|
|
||||||
|
# Configure grid weights
|
||||||
|
self.root.columnconfigure(0, weight=1)
|
||||||
|
self.root.rowconfigure(0, weight=1)
|
||||||
|
main_frame.columnconfigure(1, weight=1)
|
||||||
|
main_frame.rowconfigure(2, weight=1)
|
||||||
|
|
||||||
|
# Title
|
||||||
|
title_label = ttk.Label(main_frame, text="Voice to Text Converter",
|
||||||
|
font=('Arial', 16, 'bold'))
|
||||||
|
title_label.grid(row=0, column=0, columnspan=2, pady=(0, 20))
|
||||||
|
|
||||||
|
# Record button
|
||||||
|
self.record_button = ttk.Button(main_frame, text="🎤 Record",
|
||||||
|
command=self.toggle_recording,
|
||||||
|
style="Record.TButton")
|
||||||
|
self.record_button.grid(row=1, column=0, columnspan=2, pady=10, sticky="ew")
|
||||||
|
|
||||||
|
# Status label
|
||||||
|
self.status_label = ttk.Label(main_frame, text="Ready to record (Press F1 or click Record)",
|
||||||
|
font=('Arial', 10))
|
||||||
|
self.status_label.grid(row=2, column=0, columnspan=2, pady=(0, 10))
|
||||||
|
|
||||||
|
# Results frame
|
||||||
|
results_frame = ttk.LabelFrame(main_frame, text="Transcription Results", padding="10")
|
||||||
|
results_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=10)
|
||||||
|
results_frame.columnconfigure(0, weight=1)
|
||||||
|
results_frame.rowconfigure(1, weight=1)
|
||||||
|
|
||||||
|
# Raw transcription
|
||||||
|
ttk.Label(results_frame, text="Raw Transcription:", font=('Arial', 10, 'bold')).grid(row=0, column=0, sticky=tk.W)
|
||||||
|
self.raw_text = scrolledtext.ScrolledText(results_frame, height=6, width=70)
|
||||||
|
self.raw_text.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(5, 10))
|
||||||
|
|
||||||
|
# Processed transcription
|
||||||
|
ttk.Label(results_frame, text="Processed Prompt (Copied to Clipboard):", font=('Arial', 10, 'bold')).grid(row=2, column=0, sticky=tk.W)
|
||||||
|
self.processed_text = scrolledtext.ScrolledText(results_frame, height=6, width=70)
|
||||||
|
self.processed_text.grid(row=3, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(5, 0))
|
||||||
|
|
||||||
|
# Control buttons frame
|
||||||
|
controls_frame = ttk.Frame(main_frame)
|
||||||
|
controls_frame.grid(row=4, column=0, columnspan=2, pady=10, sticky="ew")
|
||||||
|
controls_frame.columnconfigure(0, weight=1)
|
||||||
|
controls_frame.columnconfigure(1, weight=1)
|
||||||
|
controls_frame.columnconfigure(2, weight=1)
|
||||||
|
|
||||||
|
# Always on top toggle
|
||||||
|
self.always_on_top_var = tk.BooleanVar(value=self.settings.get('always_on_top', False))
|
||||||
|
always_on_top_cb = ttk.Checkbutton(controls_frame, text="Always on Top",
|
||||||
|
variable=self.always_on_top_var,
|
||||||
|
command=self.toggle_always_on_top)
|
||||||
|
always_on_top_cb.grid(row=0, column=0, sticky="w")
|
||||||
|
|
||||||
|
# Settings button
|
||||||
|
settings_btn = ttk.Button(controls_frame, text="⚙️ Settings",
|
||||||
|
command=self.open_settings)
|
||||||
|
settings_btn.grid(row=0, column=1, padx=5)
|
||||||
|
|
||||||
|
# Minimize to tray button (if tray enabled and available)
|
||||||
|
if self.settings.get('minimize_to_tray', True) and self.tray_icon:
|
||||||
|
tray_btn = ttk.Button(controls_frame, text="📌 Minimize to Tray",
|
||||||
|
command=self.minimize_to_tray)
|
||||||
|
tray_btn.grid(row=0, column=2, sticky="e")
|
||||||
|
|
||||||
|
# Hotkey info
|
||||||
|
hotkey = self.settings.get('hotkey', 'f1').upper()
|
||||||
|
info_label = ttk.Label(main_frame, text=f"💡 Tip: Press {hotkey} anywhere to start/stop recording",
|
||||||
|
font=('Arial', 9), foreground="gray")
|
||||||
|
info_label.grid(row=5, column=0, columnspan=2, pady=10)
|
||||||
|
|
||||||
|
# Configure button style
|
||||||
|
style = ttk.Style()
|
||||||
|
style.configure("Record.TButton", font=('Arial', 12, 'bold'))
|
||||||
|
|
||||||
|
def setup_hotkey(self):
|
||||||
|
"""Set up global hotkey listener"""
|
||||||
|
def on_hotkey():
|
||||||
|
# Schedule the toggle in the main thread
|
||||||
|
self.root.after(0, self.toggle_recording)
|
||||||
|
|
||||||
|
# Get hotkey from settings
|
||||||
|
hotkey = self.settings.get('hotkey', 'f1')
|
||||||
|
|
||||||
|
# Start hotkey listener in background thread
|
||||||
|
self.hotkey_listener = keyboard.GlobalHotKeys({
|
||||||
|
f'<{hotkey}>': on_hotkey
|
||||||
|
})
|
||||||
|
self.hotkey_listener.start()
|
||||||
|
|
||||||
|
def setup_tray(self):
|
||||||
|
"""Set up system tray icon"""
|
||||||
|
try:
|
||||||
|
# Create a simple icon (avoid emoji text which can cause issues)
|
||||||
|
image = Image.new('RGB', (64, 64), color='blue')
|
||||||
|
draw = ImageDraw.Draw(image)
|
||||||
|
draw.ellipse([16, 16, 48, 48], fill='white')
|
||||||
|
draw.ellipse([24, 24, 40, 40], fill='blue') # Simple microphone representation
|
||||||
|
|
||||||
|
# Create tray menu
|
||||||
|
menu = pystray.Menu(
|
||||||
|
pystray.MenuItem('Show', self.show_window),
|
||||||
|
pystray.MenuItem('Record', self.toggle_recording),
|
||||||
|
pystray.MenuItem('Settings', self.open_settings),
|
||||||
|
pystray.MenuItem('Quit', self.quit_app)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.tray_icon = pystray.Icon('VoiceToText', image, 'Voice to Text', menu)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Warning: Could not set up system tray: {e}")
|
||||||
|
print("System tray features will be disabled.")
|
||||||
|
self.tray_icon = None
|
||||||
|
# Disable tray setting if it fails
|
||||||
|
self.settings.set('minimize_to_tray', False)
|
||||||
|
|
||||||
|
def toggle_always_on_top(self):
|
||||||
|
"""Toggle always on top setting"""
|
||||||
|
always_on_top = self.always_on_top_var.get()
|
||||||
|
self.root.wm_attributes('-topmost', always_on_top)
|
||||||
|
self.settings.set('always_on_top', always_on_top)
|
||||||
|
|
||||||
|
def minimize_to_tray(self):
|
||||||
|
"""Minimize window to system tray"""
|
||||||
|
if self.tray_icon:
|
||||||
|
self.root.withdraw()
|
||||||
|
# Start tray icon in background thread
|
||||||
|
threading.Thread(target=self.tray_icon.run, daemon=True).start()
|
||||||
|
else:
|
||||||
|
# If tray is not available, just minimize normally
|
||||||
|
self.root.iconify()
|
||||||
|
messagebox.showinfo("Minimized", "Window minimized to taskbar (system tray not available)")
|
||||||
|
|
||||||
|
def show_window(self, icon=None, item=None):
|
||||||
|
"""Show window from tray"""
|
||||||
|
self.root.deiconify()
|
||||||
|
self.root.lift()
|
||||||
|
if self.tray_icon:
|
||||||
|
self.tray_icon.stop()
|
||||||
|
|
||||||
|
def open_settings(self, icon=None, item=None):
|
||||||
|
"""Open settings dialog"""
|
||||||
|
SettingsDialog(self.root, self.settings, self.apply_settings)
|
||||||
|
|
||||||
|
def apply_settings(self):
|
||||||
|
"""Apply new settings to the application"""
|
||||||
|
# Update hotkey
|
||||||
|
if self.hotkey_listener:
|
||||||
|
self.hotkey_listener.stop()
|
||||||
|
self.setup_hotkey()
|
||||||
|
|
||||||
|
# Update always on top
|
||||||
|
always_on_top = self.settings.get('always_on_top', False)
|
||||||
|
self.always_on_top_var.set(always_on_top)
|
||||||
|
self.root.wm_attributes('-topmost', always_on_top)
|
||||||
|
|
||||||
|
# Update hotkey info label
|
||||||
|
hotkey = self.settings.get('hotkey', 'f1').upper()
|
||||||
|
# Find and update the info label (this is a bit hacky but works)
|
||||||
|
for widget in self.root.winfo_children():
|
||||||
|
for child in widget.winfo_children():
|
||||||
|
if isinstance(child, ttk.Label) and '💡 Tip:' in child.cget('text'):
|
||||||
|
child.config(text=f"💡 Tip: Press {hotkey} anywhere to start/stop recording")
|
||||||
|
|
||||||
|
def quit_app(self, icon=None, item=None):
|
||||||
|
"""Quit the application completely"""
|
||||||
|
self.is_closing = True
|
||||||
|
if self.tray_icon:
|
||||||
|
self.tray_icon.stop()
|
||||||
|
if self.hotkey_listener:
|
||||||
|
self.hotkey_listener.stop()
|
||||||
|
self.root.quit()
|
||||||
|
self.root.destroy()
|
||||||
|
|
||||||
|
def toggle_recording(self):
|
||||||
|
"""Toggle recording state"""
|
||||||
|
if not self.is_recording:
|
||||||
|
self.start_recording()
|
||||||
|
else:
|
||||||
|
self.stop_recording()
|
||||||
|
|
||||||
|
def start_recording(self):
|
||||||
|
"""Start recording in background thread"""
|
||||||
|
if self.is_recording:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_recording = True
|
||||||
|
self.record_button.config(text="🛑 Stop Recording", style="Stop.TButton")
|
||||||
|
self.status_label.config(text="🔴 Recording... Click Stop or press F1 to finish")
|
||||||
|
|
||||||
|
# Configure stop button style
|
||||||
|
style = ttk.Style()
|
||||||
|
style.configure("Stop.TButton", font=('Arial', 12, 'bold'), foreground="red")
|
||||||
|
|
||||||
|
# Clear previous results
|
||||||
|
self.raw_text.delete(1.0, tk.END)
|
||||||
|
self.processed_text.delete(1.0, tk.END)
|
||||||
|
|
||||||
|
# Start recording in background thread
|
||||||
|
threading.Thread(target=self._record_audio, daemon=True).start()
|
||||||
|
|
||||||
|
def _record_audio(self):
|
||||||
|
"""Background recording method"""
|
||||||
|
try:
|
||||||
|
# Start recording
|
||||||
|
self.recorder.recording = True
|
||||||
|
self.recorder.audio_data = []
|
||||||
|
|
||||||
|
def callback(indata, frames, time, status):
|
||||||
|
if self.recorder.recording:
|
||||||
|
self.recorder.audio_data.append(indata.copy())
|
||||||
|
|
||||||
|
# Update status in main thread
|
||||||
|
self.root.after(0, lambda: self.status_label.config(text="🔴 Recording... Speak now!"))
|
||||||
|
|
||||||
|
with sd.InputStream(callback=callback,
|
||||||
|
samplerate=self.recorder.sample_rate,
|
||||||
|
channels=self.recorder.channels,
|
||||||
|
dtype=np.float32):
|
||||||
|
# Wait until recording is stopped
|
||||||
|
while self.is_recording:
|
||||||
|
threading.Event().wait(0.1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.root.after(0, lambda: self._handle_recording_error(str(e)))
|
||||||
|
|
||||||
|
def stop_recording(self):
|
||||||
|
"""Stop recording and process audio"""
|
||||||
|
if not self.is_recording:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.is_recording = False
|
||||||
|
self.recorder.recording = False
|
||||||
|
|
||||||
|
self.record_button.config(text="🎤 Record", style="Record.TButton")
|
||||||
|
self.status_label.config(text="⏳ Processing transcription...")
|
||||||
|
|
||||||
|
# Process audio in background thread
|
||||||
|
threading.Thread(target=self._process_audio, daemon=True).start()
|
||||||
|
|
||||||
|
def _process_audio(self):
|
||||||
|
"""Process recorded audio and update GUI"""
|
||||||
|
try:
|
||||||
|
if not self.recorder.audio_data:
|
||||||
|
self.root.after(0, lambda: self._handle_recording_error("No audio recorded"))
|
||||||
|
return
|
||||||
|
|
||||||
|
# Combine audio data
|
||||||
|
audio = np.concatenate(self.recorder.audio_data, axis=0)
|
||||||
|
|
||||||
|
# Update status
|
||||||
|
self.root.after(0, lambda: self.status_label.config(text="🤖 Loading Whisper model..."))
|
||||||
|
|
||||||
|
# Load model and transcribe
|
||||||
|
model_name = self.settings.get('whisper_model', 'base') if hasattr(self, 'settings') else 'base'
|
||||||
|
model = whisper.load_model(model_name)
|
||||||
|
temp_file = self.recorder._save_to_temp_file(audio)
|
||||||
|
|
||||||
|
self.root.after(0, lambda: self.status_label.config(text="🤖 Transcribing audio..."))
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = model.transcribe(temp_file)
|
||||||
|
raw_text = result["text"]
|
||||||
|
processed_text = self.recorder.processor.process(raw_text)
|
||||||
|
|
||||||
|
# Update GUI in main thread
|
||||||
|
self.root.after(0, lambda: self._update_results(raw_text, processed_text))
|
||||||
|
|
||||||
|
# Save to file
|
||||||
|
self._save_transcription(raw_text, processed_text)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
os.unlink(temp_file)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.root.after(0, lambda: self._handle_recording_error(str(e)))
|
||||||
|
|
||||||
|
def _update_results(self, raw_text, processed_text):
|
||||||
|
"""Update GUI with transcription results"""
|
||||||
|
# Update text widgets
|
||||||
|
self.raw_text.delete(1.0, tk.END)
|
||||||
|
self.raw_text.insert(1.0, raw_text)
|
||||||
|
|
||||||
|
self.processed_text.delete(1.0, tk.END)
|
||||||
|
self.processed_text.insert(1.0, processed_text)
|
||||||
|
|
||||||
|
# Copy to clipboard if enabled
|
||||||
|
if self.settings.get('auto_copy_clipboard', True):
|
||||||
|
try:
|
||||||
|
pyperclip.copy(processed_text)
|
||||||
|
self.status_label.config(text="✅ Transcription complete! Processed prompt copied to clipboard.")
|
||||||
|
except Exception as e:
|
||||||
|
self.status_label.config(text="✅ Transcription complete! (Clipboard copy failed)")
|
||||||
|
else:
|
||||||
|
self.status_label.config(text="✅ Transcription complete!")
|
||||||
|
|
||||||
|
def _save_transcription(self, raw_text, processed_text):
|
||||||
|
"""Save transcription to file"""
|
||||||
|
try:
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
output_file = self.recorder.transcripts_dir / f"transcription_{timestamp}.txt"
|
||||||
|
|
||||||
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(f"Transcription - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write("RAW TRANSCRIPTION:\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write(raw_text + "\n\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write("PROCESSED PROMPT:\n")
|
||||||
|
f.write("="*60 + "\n")
|
||||||
|
f.write(processed_text)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error saving file: {e}")
|
||||||
|
|
||||||
|
def _handle_recording_error(self, error_msg):
|
||||||
|
"""Handle recording errors"""
|
||||||
|
self.is_recording = False
|
||||||
|
self.recorder.recording = False
|
||||||
|
self.record_button.config(text="🎤 Record", style="Record.TButton")
|
||||||
|
self.status_label.config(text=f"❌ Error: {error_msg}")
|
||||||
|
messagebox.showerror("Recording Error", error_msg)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Start the GUI application"""
|
||||||
|
try:
|
||||||
|
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||||
|
self.root.bind('<Configure>', lambda e: self.save_window_geometry() if e.widget == self.root else None)
|
||||||
|
self.root.mainloop()
|
||||||
|
finally:
|
||||||
|
self.save_window_geometry()
|
||||||
|
if self.hotkey_listener:
|
||||||
|
self.hotkey_listener.stop()
|
||||||
|
if self.tray_icon:
|
||||||
|
self.tray_icon.stop()
|
||||||
|
|
||||||
|
def on_closing(self):
|
||||||
|
"""Handle window closing"""
|
||||||
|
if self.settings.get('minimize_to_tray', True) and not self.is_closing and self.tray_icon:
|
||||||
|
# Minimize to tray instead of closing (only if tray is available)
|
||||||
|
self.minimize_to_tray()
|
||||||
|
else:
|
||||||
|
# Actually close
|
||||||
|
self.quit_app()
|
||||||
|
|
||||||
|
def save_window_geometry(self):
|
||||||
|
"""Save current window geometry"""
|
||||||
|
try:
|
||||||
|
geometry = self.root.geometry()
|
||||||
|
self.settings.set('window_geometry', geometry)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main_terminal():
|
||||||
|
"""Terminal version of the voice recorder"""
|
||||||
|
recorder = VoiceRecorder()
|
||||||
|
|
||||||
|
print("Voice to Text Converter (Terminal Mode)")
|
||||||
|
print("=======================================")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
print("\n1. Record (Enter to stop)")
|
||||||
|
print("2. Quit")
|
||||||
|
|
||||||
|
choice = input("\nSelect option (1-2): ").strip()
|
||||||
|
|
||||||
|
if choice == "1":
|
||||||
|
recorder.record_audio()
|
||||||
|
elif choice == "2":
|
||||||
|
print("Goodbye!")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("Invalid choice. Please select 1 or 2.")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main entry point - check for UI argument"""
|
||||||
|
if len(sys.argv) > 1 and sys.argv[1].lower() == 'ui':
|
||||||
|
# Launch GUI version
|
||||||
|
print("Starting Voice to Text Converter (GUI Mode)...")
|
||||||
|
app = VoiceRecorderGUI()
|
||||||
|
app.run()
|
||||||
|
else:
|
||||||
|
# Launch terminal version
|
||||||
|
main_terminal()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
29
voice_to_text_gui.bat
Normal file
29
voice_to_text_gui.bat
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@echo off
|
||||||
|
title Voice to Text Converter - GUI Mode
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
REM Check if Python is available
|
||||||
|
python --version >nul 2>&1
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] Python is not installed or not in PATH
|
||||||
|
echo.
|
||||||
|
echo Please run setup.bat first to install dependencies
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check if voice_to_text.py exists
|
||||||
|
if not exist "voice_to_text.py" (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] voice_to_text.py not found
|
||||||
|
echo Make sure you're running this from the correct directory
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Start the GUI application and close this batch window
|
||||||
|
echo Starting Voice to Text Converter (GUI Mode)...
|
||||||
|
pythonw voice_to_text.py ui
|
||||||
9
voice_to_text_settings.json
Normal file
9
voice_to_text_settings.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"hotkey": "f1",
|
||||||
|
"always_on_top": false,
|
||||||
|
"minimize_to_tray": true,
|
||||||
|
"whisper_model": "base",
|
||||||
|
"window_geometry": "566x508+-609+28",
|
||||||
|
"auto_copy_clipboard": true,
|
||||||
|
"test_key": "test_value"
|
||||||
|
}
|
||||||
153
voice_to_text_technical.md
Normal file
153
voice_to_text_technical.md
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
# Voice-to-Text Technical Documentation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The `voice_to_text.py` script is an enhanced voice recording and transcription system that converts speech to text using OpenAI's Whisper model, with intelligent processing to create optimized prompts for Claude Code.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
#### 1. PromptProcessor Class
|
||||||
|
**Purpose**: Transforms raw transcriptions into Claude Code-optimized prompts
|
||||||
|
|
||||||
|
**Key Features**:
|
||||||
|
- Pattern-based text replacement using regex
|
||||||
|
- Context-aware transformations for development workflows
|
||||||
|
- Automatic capitalization and punctuation correction
|
||||||
|
|
||||||
|
**Pattern Categories**:
|
||||||
|
- **Agent References**: Converts natural speech about agents to `@agent` format
|
||||||
|
- **Tool References**: Transforms tool mentions to `@tool` format
|
||||||
|
- **File/Directory References**: Standardizes file and directory mentions
|
||||||
|
- **Code Elements**: Formats function, class, and variable references with backticks
|
||||||
|
- **Task Management**: Optimizes todo and task-related language
|
||||||
|
- **Commands**: Standardizes common development commands
|
||||||
|
|
||||||
|
#### 2. VoiceRecorder Class
|
||||||
|
**Purpose**: Handles audio recording, transcription, and output processing
|
||||||
|
|
||||||
|
**Key Features**:
|
||||||
|
- Real-time audio recording with configurable duration
|
||||||
|
- Whisper model integration for speech-to-text
|
||||||
|
- Automatic transcript organization in `/transcripts` folder
|
||||||
|
- Clipboard integration for immediate prompt usage
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
|
||||||
|
1. **Audio Capture**: Records microphone input using sounddevice
|
||||||
|
2. **Audio Processing**: Converts to WAV format for Whisper compatibility
|
||||||
|
3. **Transcription**: Uses Whisper model to convert speech to text
|
||||||
|
4. **Text Processing**: Applies intelligent pattern matching via PromptProcessor
|
||||||
|
5. **Output**: Displays both raw and processed text, copies to clipboard
|
||||||
|
6. **Storage**: Saves complete transcript to timestamped file in `/transcripts`
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Audio Settings
|
||||||
|
- **Sample Rate**: 16kHz (configurable)
|
||||||
|
- **Channels**: Mono (configurable)
|
||||||
|
- **Format**: 16-bit WAV for Whisper compatibility
|
||||||
|
|
||||||
|
### Whisper Model
|
||||||
|
- **Default Model**: `base` (good balance of speed/accuracy)
|
||||||
|
- **Alternatives**: `tiny`, `small`, `medium`, `large`, `turbo`
|
||||||
|
- **Language**: Auto-detected
|
||||||
|
|
||||||
|
### File Organization
|
||||||
|
- **Transcript Location**: `./transcripts/transcription_YYYYMMDD_HHMMSS.txt`
|
||||||
|
- **Naming Convention**: ISO timestamp format for chronological sorting
|
||||||
|
- **Content Structure**: Raw transcription + processed prompt in single file
|
||||||
|
|
||||||
|
## Pattern Matching System
|
||||||
|
|
||||||
|
### Regex Patterns
|
||||||
|
The system uses compiled regex patterns for efficient text transformation:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Example patterns
|
||||||
|
(r'\\buse agent ([\\w-]+)\\b', r'@agent \\1') # Agent calls
|
||||||
|
(r'\\brun tool (\\w+)\\b', r'@tool \\1') # Tool references
|
||||||
|
(r'\\bfile ([\\w/\\\\.-]+\\.[\\w]+)\\b', r'@file \\1') # File references
|
||||||
|
```
|
||||||
|
|
||||||
|
### Processing Order
|
||||||
|
1. Agent and tool references (highest priority)
|
||||||
|
2. File and directory references
|
||||||
|
3. Code element formatting
|
||||||
|
4. Task management language
|
||||||
|
5. Command standardization
|
||||||
|
6. Final capitalization and punctuation
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
### Required Packages
|
||||||
|
- `whisper`: OpenAI's speech recognition model
|
||||||
|
- `sounddevice`: Cross-platform audio recording
|
||||||
|
- `pyperclip`: Cross-platform clipboard access
|
||||||
|
- `numpy`: Audio data processing
|
||||||
|
- `torch`: PyTorch backend for Whisper
|
||||||
|
|
||||||
|
### System Requirements
|
||||||
|
- **Python**: 3.8+
|
||||||
|
- **Audio**: Microphone access
|
||||||
|
- **Platform**: Windows/Mac/Linux clipboard support
|
||||||
|
- **Memory**: Sufficient RAM for Whisper model (varies by model size)
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Audio Issues
|
||||||
|
- Microphone permission checks
|
||||||
|
- Device availability validation
|
||||||
|
- Recording timeout handling
|
||||||
|
|
||||||
|
### Transcription Issues
|
||||||
|
- Model loading error recovery
|
||||||
|
- Empty audio detection
|
||||||
|
- Whisper processing timeouts
|
||||||
|
|
||||||
|
### Clipboard Issues
|
||||||
|
- Platform-specific clipboard access
|
||||||
|
- Fallback to manual copy instructions
|
||||||
|
- Graceful degradation when pyperclip fails
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
### Model Selection
|
||||||
|
- **tiny**: Fastest, lower accuracy, ~39M parameters
|
||||||
|
- **base**: Balanced, recommended default, ~74M parameters
|
||||||
|
- **large**: Highest accuracy, slower, ~1550M parameters
|
||||||
|
|
||||||
|
### Memory Usage
|
||||||
|
- Model caching reduces load times
|
||||||
|
- Audio buffer management for long recordings
|
||||||
|
- Transcript file size monitoring
|
||||||
|
|
||||||
|
### Processing Speed
|
||||||
|
- Pattern matching is O(n) with text length
|
||||||
|
- Clipboard operations are near-instantaneous
|
||||||
|
- File I/O is optimized for small transcript files
|
||||||
|
|
||||||
|
## Extensibility
|
||||||
|
|
||||||
|
### Adding New Patterns
|
||||||
|
```python
|
||||||
|
# Add to PromptProcessor.__init__()
|
||||||
|
self.patterns.append((
|
||||||
|
r'\\bnew pattern\\b', # Regex pattern
|
||||||
|
r'replacement text' # Replacement string
|
||||||
|
))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Processing
|
||||||
|
The `PromptProcessor.process()` method can be extended with:
|
||||||
|
- Additional text transformations
|
||||||
|
- Context-aware replacements
|
||||||
|
- Language-specific processing
|
||||||
|
- User-defined pattern files
|
||||||
|
|
||||||
|
### Integration Points
|
||||||
|
- Pre/post-processing hooks
|
||||||
|
- Custom clipboard formatters
|
||||||
|
- Alternative output destinations
|
||||||
|
- Real-time processing callbacks
|
||||||
38
voice_to_text_terminal.bat
Normal file
38
voice_to_text_terminal.bat
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
@echo off
|
||||||
|
title Voice to Text Converter - Terminal Mode
|
||||||
|
cd /d "%~dp0"
|
||||||
|
|
||||||
|
REM Check if Python is available
|
||||||
|
python --version >nul 2>&1
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] Python is not installed or not in PATH
|
||||||
|
echo.
|
||||||
|
echo Please run setup.bat first to install dependencies
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check if voice_to_text.py exists
|
||||||
|
if not exist "voice_to_text.py" (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] voice_to_text.py not found
|
||||||
|
echo Make sure you're running this from the correct directory
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Run the application in terminal mode
|
||||||
|
echo Starting Voice to Text Converter (Terminal Mode)...
|
||||||
|
echo.
|
||||||
|
python voice_to_text.py
|
||||||
|
|
||||||
|
REM Keep window open if there was an error
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo.
|
||||||
|
echo [ERROR] Application exited with an error
|
||||||
|
echo.
|
||||||
|
pause
|
||||||
|
)
|
||||||
325
voice_to_text_user_guide.md
Normal file
325
voice_to_text_user_guide.md
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
# Voice-to-Text User Guide
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Terminal Mode (Default)
|
||||||
|
1. **Run the script**: `python voice_to_text.py`
|
||||||
|
2. **Choose option 1**: Record (Enter to stop)
|
||||||
|
3. **Speak your prompt**: Use natural language with smart commands
|
||||||
|
4. **Get your prompt**: Processed text is automatically copied to clipboard
|
||||||
|
5. **Paste in Claude Code**: Ctrl+V to paste the optimized prompt
|
||||||
|
|
||||||
|
### GUI Mode
|
||||||
|
1. **Run with UI flag**: `python voice_to_text.py ui`
|
||||||
|
2. **Click Record button** or **press F1** anywhere to start recording
|
||||||
|
3. **Speak your prompt**: Use natural language with smart commands
|
||||||
|
4. **Click Stop** or **press F1 again** to finish recording
|
||||||
|
5. **Get your prompt**: Processed text is automatically copied to clipboard
|
||||||
|
6. **Paste in Claude Code**: Ctrl+V to paste the optimized prompt
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Python 3.8 or higher
|
||||||
|
- Microphone access
|
||||||
|
- Internet connection (for initial Whisper model download)
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Run the script
|
||||||
|
python voice_to_text.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
|
||||||
|
### Terminal Mode
|
||||||
|
- **Option 1**: Record (Press Enter to stop)
|
||||||
|
- Choose option `1`
|
||||||
|
- Speak your prompt after \"Recording...\" appears
|
||||||
|
- Press Enter to stop recording
|
||||||
|
- **Option 2**: Quit
|
||||||
|
- Choose option `2` to exit the program
|
||||||
|
|
||||||
|
### GUI Mode
|
||||||
|
- **Global Hotkey**: Press F1 (or custom key) anywhere on your system to start/stop recording
|
||||||
|
- **Record Button**: Click the microphone button to start/stop recording
|
||||||
|
- **Visual Feedback**: Button changes color and text during recording
|
||||||
|
- **Real-time Status**: Status bar shows current recording state
|
||||||
|
- **Results Display**: Both raw and processed transcriptions shown in text areas
|
||||||
|
- **Always on Top**: Optional setting to keep window visible above other apps
|
||||||
|
- **System Tray**: Minimize to tray, access from system tray icon
|
||||||
|
- **Settings**: Configurable hotkeys, Whisper models, and preferences
|
||||||
|
|
||||||
|
### Smart Voice Commands
|
||||||
|
|
||||||
|
The system automatically converts natural speech into Claude Code-optimized prompts:
|
||||||
|
|
||||||
|
#### Agent Commands
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| \"use agent python-pro\" | `@agent python-pro` |
|
||||||
|
| \"launch agent debug specialist\" | `@agent debug-specialist` |
|
||||||
|
| \"call agent javascript pro\" | `@agent javascript-pro` |
|
||||||
|
|
||||||
|
#### Tool References
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| \"run tool bash\" | `@tool bash` |
|
||||||
|
| \"use the grep tool\" | `@tool grep` |
|
||||||
|
| \"call the read tool\" | `@tool read` |
|
||||||
|
|
||||||
|
#### File & Directory References
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| \"directory downloads\" | `@dir downloads/` |
|
||||||
|
| \"file package.json\" | `@file package.json` |
|
||||||
|
| \"the readme file\" | `@file README.md` |
|
||||||
|
| \"folder source\" | `@dir source/` |
|
||||||
|
|
||||||
|
#### Code Elements
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| \"function get user\" | `` `getUser()` function`` |
|
||||||
|
| \"class user manager\" | `` `UserManager` class`` |
|
||||||
|
| \"variable user name\" | `` `userName` variable`` |
|
||||||
|
| \"method save data\" | `` `saveData()` method`` |
|
||||||
|
|
||||||
|
#### Task Management
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| \"add to todo\" | `add to todo:` |
|
||||||
|
| \"new task\" | `new todo:` |
|
||||||
|
| \"mark complete\" | `mark todo complete` |
|
||||||
|
| \"mark done\" | `mark todo complete` |
|
||||||
|
|
||||||
|
#### Common Commands
|
||||||
|
| Say This | Gets Converted To |
|
||||||
|
|----------|-------------------|
|
||||||
|
| \"run tests\" | `run tests` |
|
||||||
|
| \"commit changes\" | `commit changes` |
|
||||||
|
| \"create pull request\" | `create PR` |
|
||||||
|
| \"install dependencies\" | `install dependencies` |
|
||||||
|
|
||||||
|
## Example Workflow
|
||||||
|
|
||||||
|
### Terminal Mode Example
|
||||||
|
1. Run `python voice_to_text.py`
|
||||||
|
2. Choose option `1` (Record)
|
||||||
|
3. Speak: *\"Use agent python pro to review file auth.py and run tests\"*
|
||||||
|
4. Press Enter to stop
|
||||||
|
5. See processed result: *\"@agent python-pro to review @file auth.py and run tests.\"*
|
||||||
|
6. Text automatically copied to clipboard
|
||||||
|
7. Choose option `1` to record again or `2` to quit
|
||||||
|
|
||||||
|
### GUI Mode Example
|
||||||
|
1. Run `python voice_to_text.py ui`
|
||||||
|
2. Press F1 (or click Record button)
|
||||||
|
3. Speak: *\"Add to todo fix the authentication bug in function login user\"*
|
||||||
|
4. Press F1 again (or click Stop)
|
||||||
|
5. See both raw and processed results in the GUI
|
||||||
|
6. Processed text: *\"Add to todo: fix the authentication bug in `loginUser()` function.\"*
|
||||||
|
7. Text automatically copied to clipboard
|
||||||
|
8. Press F1 again for next recording
|
||||||
|
|
||||||
|
### Voice Command Examples
|
||||||
|
|
||||||
|
**Testing a Feature**:
|
||||||
|
- **Say**: *\"I just finished implementing the user authentication feature. Can you use agent python pro to review the code in file auth.py and then run tests to make sure everything works?\"*
|
||||||
|
- **Gets processed to**: *\"I just finished implementing the user authentication feature. Can you @agent python-pro to review the code in @file auth.py and then run tests to make sure everything works?\"*
|
||||||
|
|
||||||
|
**File Operations**:
|
||||||
|
- **Say**: *\"Please read file package.json and check the dependencies in folder node modules then use tool bash to run npm install\"*
|
||||||
|
- **Gets processed to**: *\"Please read @file package.json and check the dependencies in @dir node_modules/ then @tool bash to run npm install.\"*
|
||||||
|
|
||||||
|
**Task Management**:
|
||||||
|
- **Say**: *\"Add to todo fix the authentication bug in function login user and mark the previous task as complete\"*
|
||||||
|
- **Gets processed to**: *\"Add to todo: fix the authentication bug in `loginUser()` function and mark todo complete.\"*
|
||||||
|
|
||||||
|
## Tips for Better Results
|
||||||
|
|
||||||
|
### Speaking Clearly
|
||||||
|
- Speak at normal pace (not too fast or slow)
|
||||||
|
- Use clear pronunciation
|
||||||
|
- Pause briefly between different concepts
|
||||||
|
- Speak in a quiet environment
|
||||||
|
|
||||||
|
### Effective Commands
|
||||||
|
- Use specific file names: \"file config.json\" not \"the config file\"
|
||||||
|
- Mention directories explicitly: \"directory source\" not \"the source\"
|
||||||
|
- Use consistent naming: \"function getUserData\" not \"the get user data function\"
|
||||||
|
|
||||||
|
### Natural Language
|
||||||
|
- Speak naturally - the system handles capitalization and punctuation
|
||||||
|
- Use complete sentences when possible
|
||||||
|
- Don't worry about perfect grammar - focus on clarity
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
### What You See
|
||||||
|
1. **Raw Transcription**: Exactly what Whisper heard
|
||||||
|
2. **Processed Prompt**: Optimized version for Claude Code
|
||||||
|
3. **Clipboard Confirmation**: \"✓ Processed prompt copied to clipboard!\"
|
||||||
|
4. **File Location**: Path to saved transcript in `/transcripts` folder
|
||||||
|
|
||||||
|
### File Storage
|
||||||
|
All transcripts are saved in the `transcripts/` folder with timestamps:
|
||||||
|
- **Format**: `transcription_YYYYMMDD_HHMMSS.txt`
|
||||||
|
- **Content**: Both raw and processed versions
|
||||||
|
- **Sorting**: Files are chronologically ordered
|
||||||
|
|
||||||
|
## Mode Comparison
|
||||||
|
|
||||||
|
| Feature | Terminal Mode | GUI Mode |
|
||||||
|
|---------|---------------|----------|
|
||||||
|
| **Launch** | `python voice_to_text.py` | `python voice_to_text.py ui` |
|
||||||
|
| **Recording** | Enter to stop | Button or custom hotkey |
|
||||||
|
| **Global Hotkey** | ❌ No | ✅ Customizable (F1-F12) |
|
||||||
|
| **Visual Feedback** | Text only | Button colors, status bar |
|
||||||
|
| **Results Display** | Console output | Scrollable text areas |
|
||||||
|
| **Multiple Sessions** | Menu driven | Always available |
|
||||||
|
| **Background Use** | ❌ Terminal focused | ✅ Hotkey works anywhere |
|
||||||
|
| **Always on Top** | ❌ No | ✅ Optional setting |
|
||||||
|
| **System Tray** | ❌ No | ✅ Minimize to tray |
|
||||||
|
| **Settings** | ❌ No | ✅ Full settings dialog |
|
||||||
|
| **Best For** | Quick one-off recordings | Continuous workflow |
|
||||||
|
|
||||||
|
## Advanced Usage
|
||||||
|
|
||||||
|
### GUI Settings Dialog
|
||||||
|
|
||||||
|
Access settings through:
|
||||||
|
1. **Settings Button**: Click the ⚙️ Settings button in the GUI
|
||||||
|
2. **System Tray**: Right-click tray icon → Settings (when minimized)
|
||||||
|
|
||||||
|
**Available Settings**:
|
||||||
|
- **Global Hotkey**: Choose F1-F12 for recording control
|
||||||
|
- **Whisper Model**: Select from tiny, base, small, medium, large, turbo
|
||||||
|
- **Always on Top**: Keep window above other applications
|
||||||
|
- **Minimize to Tray**: Hide to system tray instead of closing
|
||||||
|
- **Auto Copy Clipboard**: Automatically copy processed text
|
||||||
|
|
||||||
|
**Model Trade-offs**:
|
||||||
|
- **tiny**: Fastest, least accurate (~39M parameters)
|
||||||
|
- **base**: Balanced, recommended (~74M parameters)
|
||||||
|
- **large**: Most accurate, slower (~1550M parameters)
|
||||||
|
- **turbo**: Fast and accurate (~809M parameters)
|
||||||
|
|
||||||
|
### System Tray Features
|
||||||
|
|
||||||
|
When minimized to tray, right-click the tray icon for:
|
||||||
|
- **Show**: Restore the main window
|
||||||
|
- **Record**: Start/stop recording directly from tray
|
||||||
|
- **Settings**: Open settings dialog
|
||||||
|
- **Quit**: Exit the application completely
|
||||||
|
|
||||||
|
### Settings File
|
||||||
|
|
||||||
|
Settings are automatically saved to `voice_to_text_settings.json` with:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
\"hotkey\": \"f1\",
|
||||||
|
\"always_on_top\": false,
|
||||||
|
\"minimize_to_tray\": true,
|
||||||
|
\"whisper_model\": \"base\",
|
||||||
|
\"auto_copy_clipboard\": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Customization
|
||||||
|
|
||||||
|
For advanced users, you can:
|
||||||
|
1. **Add Custom Patterns**: Edit the `PromptProcessor` class patterns list
|
||||||
|
2. **Modify Default Settings**: Edit `default_settings` in `SettingsManager`
|
||||||
|
3. **Custom Hotkeys**: Use any key combination supported by pynput
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Audio Issues
|
||||||
|
**Problem**: \"No microphone detected\"
|
||||||
|
- **Solution**: Check microphone permissions and connections
|
||||||
|
- **Windows**: Settings > Privacy > Microphone
|
||||||
|
- **Mac**: System Preferences > Security & Privacy > Microphone
|
||||||
|
|
||||||
|
**Problem**: \"Recording sounds muffled\"
|
||||||
|
- **Solution**: Check microphone positioning and background noise
|
||||||
|
- Move closer to microphone
|
||||||
|
- Reduce background noise
|
||||||
|
|
||||||
|
### GUI Mode Issues
|
||||||
|
**Problem**: \"F1 hotkey not working\"
|
||||||
|
- **Solution**:
|
||||||
|
- Check if another application is using F1
|
||||||
|
- Try running as administrator (Windows)
|
||||||
|
- Restart the application
|
||||||
|
|
||||||
|
**Problem**: \"GUI window not responding\"
|
||||||
|
- **Solution**:
|
||||||
|
- Wait for Whisper model to load (first time is slow)
|
||||||
|
- Check task manager for hung processes
|
||||||
|
- Restart the application
|
||||||
|
|
||||||
|
### Transcription Issues
|
||||||
|
**Problem**: \"Poor transcription accuracy\"
|
||||||
|
- **Solution**:
|
||||||
|
- Speak more clearly and slowly
|
||||||
|
- Reduce background noise
|
||||||
|
- Check microphone quality
|
||||||
|
- Consider upgrading to larger Whisper model
|
||||||
|
|
||||||
|
**Problem**: \"Model loading takes too long\"
|
||||||
|
- **Solution**: First run downloads the model (~150MB for base model)
|
||||||
|
- Subsequent runs are much faster
|
||||||
|
- Consider using smaller `tiny` model for speed
|
||||||
|
|
||||||
|
### Clipboard Issues
|
||||||
|
**Problem**: \"Could not copy to clipboard\"
|
||||||
|
- **Solution**:
|
||||||
|
- Copy the processed text manually
|
||||||
|
- Check clipboard permissions
|
||||||
|
- Restart the application
|
||||||
|
|
||||||
|
### Processing Issues
|
||||||
|
**Problem**: \"Smart commands not working\"
|
||||||
|
- **Solution**:
|
||||||
|
- Check pronunciation of keywords
|
||||||
|
- Use exact phrases from the reference table
|
||||||
|
- Speak clearly and pause between concepts
|
||||||
|
|
||||||
|
## Advanced Usage
|
||||||
|
|
||||||
|
### Changing Whisper Model
|
||||||
|
Edit line 29 in `voice_to_text.py`:
|
||||||
|
```python
|
||||||
|
model = whisper.load_model(\"base\") # Change to: tiny, small, medium, large, turbo
|
||||||
|
```
|
||||||
|
|
||||||
|
**Model Trade-offs**:
|
||||||
|
- **tiny**: Fastest, least accurate
|
||||||
|
- **base**: Balanced (recommended)
|
||||||
|
- **large**: Most accurate, slower
|
||||||
|
|
||||||
|
### Adding Custom Patterns
|
||||||
|
To add your own smart commands, edit the `PromptProcessor` class patterns list in `voice_to_text.py`.
|
||||||
|
|
||||||
|
### Batch Processing
|
||||||
|
For processing multiple audio files, consider modifying the script to accept file arguments rather than recording live audio.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
### Common Questions
|
||||||
|
**Q**: Can I use this offline?
|
||||||
|
**A**: Yes, after the initial model download, everything runs locally.
|
||||||
|
|
||||||
|
**Q**: What audio formats are supported?
|
||||||
|
**A**: The script records in WAV format. For existing files, Whisper supports many formats.
|
||||||
|
|
||||||
|
**Q**: Can I change the recording quality?
|
||||||
|
**A**: Yes, modify the `sample_rate` parameter in the `VoiceRecorder` constructor.
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
- Check the technical documentation for implementation details
|
||||||
|
- Review the troubleshooting section above
|
||||||
|
- Ensure all dependencies are properly installed
|
||||||
Loading…
x
Reference in New Issue
Block a user