karaoke-gen 0.76.26__tar.gz → 0.81.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/PKG-INFO +5 -1
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/core/config.py +6 -5
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/config.py +7 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/langchain_bridge.py +22 -7
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/model_factory.py +25 -1
- karaoke_gen-0.81.5/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/router.py +40 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/.gitignore +1 -0
- karaoke_gen-0.81.5/lyrics_transcriber_temp/lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts +207 -0
- karaoke_gen-0.81.5/lyrics_transcriber_temp/lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json +226 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/package.json +4 -1
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/playwright.config.ts +1 -1
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +34 -30
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/Header.tsx +153 -49
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +120 -3
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +11 -1
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +122 -35
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/types.ts +6 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/pyproject.toml +6 -1
- karaoke_gen-0.76.26/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/router.py +0 -35
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/LICENSE +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/README.md +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/audio_fetcher.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/audio_processor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/config.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/file_handler.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/analyzer.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/editor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/models.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/server.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/static/index.html +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/instrumental_review/waveform.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/karaoke_finalise/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/karaoke_finalise/karaoke_finalise.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/karaoke_gen.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/lyrics_processor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/metadata.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/base.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/context.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/executors/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/executors/local.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/executors/remote.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/stages/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/stages/finalize.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/stages/render.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/stages/screens.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/stages/separation.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/pipeline/stages/transcription.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/resources/AvenirNext-Bold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/resources/Montserrat-Bold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/resources/Oswald-Bold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/resources/Oswald-SemiBold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/resources/Zurich_Cn_BT_Bold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/style_loader.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/utils/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/utils/bulk_cli.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/utils/cli_args.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/utils/gen_cli.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/utils/remote_cli.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/video_background_processor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/karaoke_gen/video_generator.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/cli/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/cli/cli_main.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/core/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/core/controller.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/adapter.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/agent.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/aggregator.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/collector.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/retention.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/store.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/ambiguous.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/background_vocals.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/base.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/complex_multi_error.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/extra_words.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/no_error.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/punctuation.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/registry.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/repeated_section.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/sound_alike.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/ai_correction.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/correction_session.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/enums.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/human_feedback.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/learning_data.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/observability_metrics.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/schemas.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/utils.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/langfuse_integration.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/metrics.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/performance.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/prompts/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/prompts/classifier.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/base.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/circuit_breaker.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/constants.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/health.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/response_cache.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/response_parser.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/retry_executor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/consensus_workflow.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/correction_graph.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/feedback_workflow.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/anchor_sequence.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/corrector.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/feedback/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/feedback/schemas.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/feedback/store.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/base.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/extend_anchor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/levenshtein.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/llm.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/llm_providers.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/no_space_punct_match.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/relaxed_word_count_match.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/repeat.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/sound_alike.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/syllables_match.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/word_count_match.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/word_operations.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/operations.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/phrase_analyzer.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/correction/text_utils.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/.yarn/releases/yarn-4.7.0.cjs +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/.yarnrc.yml +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/README.md +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/REPLACE_ALL_FUNCTIONALITY.md +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/eslint.config.js +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/index.html +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/package-lock.json +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/android-chrome-192x192.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/android-chrome-512x512.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/apple-touch-icon.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/favicon-16x16.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/favicon-32x32.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/favicon.ico +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/nomad-karaoke-logo.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/App.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/api.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AddLyricsModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AgenticCorrectionMetrics.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AppHeader.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AudioPlayer.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectionAnnotationModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectionDetailCard.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditActionBar.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditWordList.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/FileUpload.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/FindReplaceModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ModeSelector.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ModelSelector.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ReferenceView.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/TimelineEditor.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/TimingOffsetModal.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/WordDivider.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/constants.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/styles.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/types.js +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/localStorage.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/segmentOperations.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/timingUtils.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/wordUtils.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/hooks/useManualSync.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/main.tsx +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/theme.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/types/global.d.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/types.js +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/types.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/validation.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/vite-env.d.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.app.json +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.json +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.node.json +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.tsbuildinfo +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/update_version.js +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/vite.config.d.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/vite.config.js +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/vite.config.ts +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/android-chrome-192x192.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/android-chrome-512x512.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/apple-touch-icon.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/assets/index-BECn1o8Q.js +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/assets/index-BECn1o8Q.js.map +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/favicon-16x16.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/favicon-32x32.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/favicon.ico +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/index.html +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/frontend/yarn.lock +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/base_lyrics_provider.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/file_provider.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/genius.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/lrclib.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/musixmatch.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/spotify.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/user_input_provider.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/ass.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/ass_specs.txt +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/config.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/constants.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/event.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/formatters.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/lyrics_line.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/lyrics_screen.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/section_detector.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/section_screen.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/style.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdg.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/cdg.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/composer.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/config.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/images/instrumental.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/images/intro.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/pack.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/render.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/centertexttoplogobottomtext.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/circlein.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/circleout.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/fizzle.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/largecentertexttoplogo.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/rectangle.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/spiral.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/topleftmusicalnotes.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wipein.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wipeleft.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wipeout.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wiperight.png +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/utils.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/countdown_processor.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/AvenirNext-Bold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/DMSans-VariableFont_opsz,wght.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/DMSerifDisplay-Regular.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/Oswald-SemiBold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/Zurich_Cn_BT_Bold.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/arial.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/georgia.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/verdana.ttf +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/generator.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/lrc_to_cdg.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/lyrics_file.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/plain_text.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/segment_resizer.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/subtitles.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/output/video.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/review/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/review/server.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/storage/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/storage/dropbox.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/audioshake.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/base_transcriber.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/local_whisper.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/whisper.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/types.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/utils/__init__.py +0 -0
- {karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/utils/word_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: karaoke-gen
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.81.5
|
|
4
4
|
Summary: Generate karaoke videos with synchronized lyrics. Handles the entire process from downloading audio and lyrics to creating the final video with title screens.
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -20,6 +20,7 @@ Requires-Dist: audio-separator[cpu] (>=0.34.0)
|
|
|
20
20
|
Requires-Dist: beautifulsoup4 (>=4)
|
|
21
21
|
Requires-Dist: cattrs (>=24.1.2)
|
|
22
22
|
Requires-Dist: dropbox (>=12)
|
|
23
|
+
Requires-Dist: email-validator (>=2.0.0)
|
|
23
24
|
Requires-Dist: fastapi (>=0.104.0)
|
|
24
25
|
Requires-Dist: fetch-lyrics-from-genius (>=0.1)
|
|
25
26
|
Requires-Dist: ffmpeg-python (>=0.2.0,<0.3.0)
|
|
@@ -41,6 +42,7 @@ Requires-Dist: kbputils (>=0.0.16,<0.0.17)
|
|
|
41
42
|
Requires-Dist: langchain (>=0.3.0)
|
|
42
43
|
Requires-Dist: langchain-anthropic (>=0.2.0)
|
|
43
44
|
Requires-Dist: langchain-core (>=0.3.0)
|
|
45
|
+
Requires-Dist: langchain-google-vertexai (>=3.1.1)
|
|
44
46
|
Requires-Dist: langchain-ollama (>=0.2.0)
|
|
45
47
|
Requires-Dist: langchain-openai (>=0.2.0)
|
|
46
48
|
Requires-Dist: langfuse (>=3.0.0)
|
|
@@ -75,10 +77,12 @@ Requires-Dist: python-levenshtein (>=0.26)
|
|
|
75
77
|
Requires-Dist: python-multipart (>=0.0.20,<0.0.21)
|
|
76
78
|
Requires-Dist: python-slugify (>=8)
|
|
77
79
|
Requires-Dist: requests (>=2)
|
|
80
|
+
Requires-Dist: sendgrid (>=6.10.0)
|
|
78
81
|
Requires-Dist: shortuuid (>=1.0.13)
|
|
79
82
|
Requires-Dist: spacy (>=3.8.7)
|
|
80
83
|
Requires-Dist: spacy-syllables (>=3)
|
|
81
84
|
Requires-Dist: srsly (>=2.5.1)
|
|
85
|
+
Requires-Dist: stripe (>=7.0.0)
|
|
82
86
|
Requires-Dist: syllables (>=1)
|
|
83
87
|
Requires-Dist: syrics (>=0)
|
|
84
88
|
Requires-Dist: thefuzz (>=0.22)
|
{karaoke_gen-0.76.26 → karaoke_gen-0.81.5}/lyrics_transcriber_temp/lyrics_transcriber/core/config.py
RENAMED
|
@@ -11,12 +11,13 @@ class TranscriberConfig:
|
|
|
11
11
|
runpod_api_key: Optional[str] = None
|
|
12
12
|
whisper_runpod_id: Optional[str] = None
|
|
13
13
|
|
|
14
|
-
# Local Whisper configuration
|
|
14
|
+
# Local Whisper configuration - reads from environment variables with sensible defaults
|
|
15
|
+
# Environment variables: WHISPER_MODEL_SIZE, WHISPER_DEVICE, WHISPER_CACHE_DIR, WHISPER_LANGUAGE
|
|
15
16
|
enable_local_whisper: bool = True # Enabled by default as fallback
|
|
16
|
-
local_whisper_model_size: str = "
|
|
17
|
-
local_whisper_device: Optional[str] =
|
|
18
|
-
local_whisper_cache_dir: Optional[str] =
|
|
19
|
-
local_whisper_language: Optional[str] =
|
|
17
|
+
local_whisper_model_size: str = field(default_factory=lambda: os.getenv("WHISPER_MODEL_SIZE", "medium"))
|
|
18
|
+
local_whisper_device: Optional[str] = field(default_factory=lambda: os.getenv("WHISPER_DEVICE"))
|
|
19
|
+
local_whisper_cache_dir: Optional[str] = field(default_factory=lambda: os.getenv("WHISPER_CACHE_DIR"))
|
|
20
|
+
local_whisper_language: Optional[str] = field(default_factory=lambda: os.getenv("WHISPER_LANGUAGE"))
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
@dataclass
|
|
@@ -18,6 +18,11 @@ class ProviderConfig:
|
|
|
18
18
|
privacy_mode: bool
|
|
19
19
|
cache_dir: str
|
|
20
20
|
|
|
21
|
+
# GCP/Vertex AI settings
|
|
22
|
+
# Note: Gemini 3 models require 'global' location (not regional like us-central1)
|
|
23
|
+
gcp_project_id: Optional[str] = None
|
|
24
|
+
gcp_location: str = "global"
|
|
25
|
+
|
|
21
26
|
request_timeout_seconds: float = 30.0
|
|
22
27
|
max_retries: int = 2
|
|
23
28
|
retry_backoff_base_seconds: float = 0.2
|
|
@@ -46,6 +51,8 @@ class ProviderConfig:
|
|
|
46
51
|
openrouter_api_key=os.getenv("OPENROUTER_API_KEY"),
|
|
47
52
|
privacy_mode=os.getenv("PRIVACY_MODE", "false").lower() in {"1", "true", "yes"},
|
|
48
53
|
cache_dir=cache_dir,
|
|
54
|
+
gcp_project_id=os.getenv("GOOGLE_CLOUD_PROJECT") or os.getenv("GCP_PROJECT_ID"),
|
|
55
|
+
gcp_location=os.getenv("GCP_LOCATION", "global"),
|
|
49
56
|
request_timeout_seconds=float(os.getenv("AGENTIC_TIMEOUT_SECONDS", "30.0")),
|
|
50
57
|
max_retries=int(os.getenv("AGENTIC_MAX_RETRIES", "2")),
|
|
51
58
|
retry_backoff_base_seconds=float(os.getenv("AGENTIC_BACKOFF_BASE_SECONDS", "0.2")),
|
|
@@ -187,26 +187,41 @@ class LangChainBridge(BaseAIProvider):
|
|
|
187
187
|
|
|
188
188
|
def _invoke_model(self, prompt: str) -> str:
|
|
189
189
|
"""Invoke the chat model with a prompt.
|
|
190
|
-
|
|
190
|
+
|
|
191
191
|
This is a simple wrapper that can be passed to the retry executor.
|
|
192
|
-
|
|
192
|
+
|
|
193
193
|
Args:
|
|
194
194
|
prompt: The prompt to send
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
Returns:
|
|
197
197
|
Response content as string
|
|
198
|
-
|
|
198
|
+
|
|
199
199
|
Raises:
|
|
200
200
|
Exception: Any error from the model invocation
|
|
201
201
|
"""
|
|
202
202
|
from langchain_core.messages import HumanMessage
|
|
203
|
-
|
|
203
|
+
|
|
204
204
|
# Prepare config with session_id in metadata (Langfuse format)
|
|
205
205
|
config = {}
|
|
206
206
|
if hasattr(self, '_session_id') and self._session_id:
|
|
207
207
|
config["metadata"] = {"langfuse_session_id": self._session_id}
|
|
208
208
|
logger.debug(f"🤖 [LangChain] Invoking with session_id: {self._session_id}")
|
|
209
|
-
|
|
209
|
+
|
|
210
210
|
response = self._chat_model.invoke([HumanMessage(content=prompt)], config=config)
|
|
211
|
-
|
|
211
|
+
content = response.content
|
|
212
|
+
|
|
213
|
+
# Handle multimodal response format from Gemini 3+ models
|
|
214
|
+
# Response can be a list of content parts: [{'type': 'text', 'text': '...'}]
|
|
215
|
+
if isinstance(content, list):
|
|
216
|
+
# Extract text from the first text content part
|
|
217
|
+
for part in content:
|
|
218
|
+
if isinstance(part, dict) and part.get('type') == 'text':
|
|
219
|
+
return part.get('text', '')
|
|
220
|
+
# Fallback: concatenate all text parts
|
|
221
|
+
return ''.join(
|
|
222
|
+
part.get('text', '') if isinstance(part, dict) else str(part)
|
|
223
|
+
for part in content
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
return content
|
|
212
227
|
|
|
@@ -155,6 +155,8 @@ class ModelFactory:
|
|
|
155
155
|
return self._create_openai_model(model_name, callbacks, config)
|
|
156
156
|
elif provider == "anthropic":
|
|
157
157
|
return self._create_anthropic_model(model_name, callbacks, config)
|
|
158
|
+
elif provider in ("vertexai", "google"):
|
|
159
|
+
return self._create_vertexai_model(model_name, callbacks, config)
|
|
158
160
|
else:
|
|
159
161
|
raise ValueError(f"Unsupported provider: {provider}")
|
|
160
162
|
except ImportError as e:
|
|
@@ -197,7 +199,7 @@ class ModelFactory:
|
|
|
197
199
|
) -> Any:
|
|
198
200
|
"""Create ChatAnthropic model."""
|
|
199
201
|
from langchain_anthropic import ChatAnthropic
|
|
200
|
-
|
|
202
|
+
|
|
201
203
|
model = ChatAnthropic(
|
|
202
204
|
model=model_name,
|
|
203
205
|
timeout=config.request_timeout_seconds,
|
|
@@ -207,3 +209,25 @@ class ModelFactory:
|
|
|
207
209
|
logger.debug(f"🤖 Created Anthropic model: {model_name}")
|
|
208
210
|
return model
|
|
209
211
|
|
|
212
|
+
def _create_vertexai_model(
|
|
213
|
+
self, model_name: str, callbacks: List[Any], config: ProviderConfig
|
|
214
|
+
) -> Any:
|
|
215
|
+
"""Create ChatVertexAI model for Google Gemini via Vertex AI.
|
|
216
|
+
|
|
217
|
+
Uses Application Default Credentials (ADC) for authentication.
|
|
218
|
+
In Cloud Run, this uses the service account automatically.
|
|
219
|
+
Locally, run: gcloud auth application-default login
|
|
220
|
+
"""
|
|
221
|
+
from langchain_google_vertexai import ChatVertexAI
|
|
222
|
+
|
|
223
|
+
model = ChatVertexAI(
|
|
224
|
+
model=model_name,
|
|
225
|
+
project=config.gcp_project_id,
|
|
226
|
+
location=config.gcp_location,
|
|
227
|
+
timeout=config.request_timeout_seconds,
|
|
228
|
+
max_retries=config.max_retries,
|
|
229
|
+
callbacks=callbacks,
|
|
230
|
+
)
|
|
231
|
+
logger.debug(f"🤖 Created Vertex AI model: {model_name} (project={config.gcp_project_id})")
|
|
232
|
+
return model
|
|
233
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Dict, Any
|
|
5
|
+
|
|
6
|
+
from .providers.config import ProviderConfig
|
|
7
|
+
|
|
8
|
+
# Default model for cloud deployments - Gemini 3 Flash via Vertex AI
|
|
9
|
+
# Note: Gemini 3 models require 'global' location (not regional like us-central1)
|
|
10
|
+
DEFAULT_CLOUD_MODEL = "vertexai/gemini-3-flash-preview"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ModelRouter:
|
|
14
|
+
"""Rules-based routing by gap type/length/uncertainty (scaffold)."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, config: ProviderConfig | None = None):
|
|
17
|
+
self._config = config or ProviderConfig.from_env()
|
|
18
|
+
|
|
19
|
+
def choose_model(self, gap_type: str, uncertainty: float) -> str:
|
|
20
|
+
"""Choose appropriate model based on gap characteristics.
|
|
21
|
+
|
|
22
|
+
Returns model identifier in format "provider/model" for LangChain:
|
|
23
|
+
- "vertexai/gemini-3-flash-preview" for Gemini via Vertex AI (default)
|
|
24
|
+
- "ollama/llama3.2:latest" for local Ollama models
|
|
25
|
+
- "openai/gpt-4" for OpenAI models
|
|
26
|
+
- "anthropic/claude-3-sonnet-20240229" for Anthropic models
|
|
27
|
+
"""
|
|
28
|
+
# Check for explicit model override from environment
|
|
29
|
+
env_model = os.getenv("AGENTIC_AI_MODEL")
|
|
30
|
+
if env_model:
|
|
31
|
+
return env_model
|
|
32
|
+
|
|
33
|
+
# Privacy mode: use local Ollama
|
|
34
|
+
if self._config.privacy_mode:
|
|
35
|
+
return "ollama/llama3.2:latest"
|
|
36
|
+
|
|
37
|
+
# Default to Gemini 3 Flash for all cases (fast, cost-effective, latest capabilities)
|
|
38
|
+
return DEFAULT_CLOUD_MODEL
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
// Get __dirname equivalent in ESM
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* E2E tests for the agentic correction workflow in the lyrics transcriber frontend.
|
|
11
|
+
*
|
|
12
|
+
* These tests verify:
|
|
13
|
+
* 1. The UI loads correctly with agentic correction data
|
|
14
|
+
* 2. The AgenticCorrectionMetrics panel displays correctly
|
|
15
|
+
* 3. Corrected words are highlighted and clickable
|
|
16
|
+
* 4. The CorrectionDetailCard shows proper information
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Helper function to load fixture data
|
|
20
|
+
async function loadFixtureData(page: import('@playwright/test').Page) {
|
|
21
|
+
const fixturePath = path.join(__dirname, 'fixtures', 'agentic-correction-data.json');
|
|
22
|
+
|
|
23
|
+
// Create a file chooser promise before clicking
|
|
24
|
+
const fileChooserPromise = page.waitForEvent('filechooser');
|
|
25
|
+
|
|
26
|
+
// Click the Load File button
|
|
27
|
+
await page.getByRole('button', { name: /load file/i }).click();
|
|
28
|
+
|
|
29
|
+
// Handle the file chooser
|
|
30
|
+
const fileChooser = await fileChooserPromise;
|
|
31
|
+
await fileChooser.setFiles(fixturePath);
|
|
32
|
+
|
|
33
|
+
// Wait for data to load by asserting expected content appears
|
|
34
|
+
await expect(page.getByText('Hello,')).toBeVisible({ timeout: 5000 });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
test.describe('Agentic Correction Workflow', () => {
|
|
38
|
+
test.beforeEach(async ({ page }) => {
|
|
39
|
+
// Navigate to the app
|
|
40
|
+
await page.goto('/');
|
|
41
|
+
|
|
42
|
+
// Wait for the initial load
|
|
43
|
+
await expect(page.getByText('Lyrics Correction Review')).toBeVisible();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('should load the app in read-only mode', async ({ page }) => {
|
|
47
|
+
// Verify read-only mode alert is shown
|
|
48
|
+
await expect(page.getByText('Running in read-only mode')).toBeVisible();
|
|
49
|
+
|
|
50
|
+
// Verify Load File button is present
|
|
51
|
+
await expect(page.getByRole('button', { name: /load file/i })).toBeVisible();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('should load correction data from JSON file', async ({ page }) => {
|
|
55
|
+
await loadFixtureData(page);
|
|
56
|
+
|
|
57
|
+
// Verify we're no longer in loading state
|
|
58
|
+
await expect(page.getByText('Loading Lyrics Correction Review...')).not.toBeVisible();
|
|
59
|
+
|
|
60
|
+
// Verify expected content from fixture is visible
|
|
61
|
+
await expect(page.getByText('Hello,')).toBeVisible();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('should render transcription view after loading data', async ({ page }) => {
|
|
65
|
+
await loadFixtureData(page);
|
|
66
|
+
|
|
67
|
+
// Wait for transcription content to render
|
|
68
|
+
await expect(page.getByText('Hello,')).toBeVisible();
|
|
69
|
+
|
|
70
|
+
// Verify the Corrected Transcription header is visible
|
|
71
|
+
await expect(page.getByText('Corrected Transcription')).toBeVisible();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test.describe('UI Components', () => {
|
|
76
|
+
test('should show Load File button on initial load', async ({ page }) => {
|
|
77
|
+
await page.goto('/');
|
|
78
|
+
|
|
79
|
+
// The Load File button should be visible
|
|
80
|
+
const loadButton = page.getByRole('button', { name: /load file/i });
|
|
81
|
+
await expect(loadButton).toBeVisible();
|
|
82
|
+
|
|
83
|
+
// Should have upload icon
|
|
84
|
+
const uploadIcon = page.locator('svg[data-testid="UploadFileIcon"]');
|
|
85
|
+
await expect(uploadIcon).toBeVisible();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('should show read-only mode banner', async ({ page }) => {
|
|
89
|
+
await page.goto('/');
|
|
90
|
+
|
|
91
|
+
// The read-only alert should be visible
|
|
92
|
+
await expect(page.getByRole('alert')).toBeVisible();
|
|
93
|
+
await expect(page.getByText(/read-only mode/i)).toBeVisible();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('should have correction metrics component', async ({ page }) => {
|
|
97
|
+
await page.goto('/');
|
|
98
|
+
|
|
99
|
+
// The page structure should be there with Paper components
|
|
100
|
+
const metricsSection = page.locator('.MuiPaper-root');
|
|
101
|
+
await expect(metricsSection.first()).toBeVisible();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test.describe('File Upload Flow', () => {
|
|
106
|
+
test('should open file dialog when clicking Load File', async ({ page }) => {
|
|
107
|
+
await page.goto('/');
|
|
108
|
+
|
|
109
|
+
// Set up listener for file chooser
|
|
110
|
+
let fileChooserOpened = false;
|
|
111
|
+
page.on('filechooser', () => {
|
|
112
|
+
fileChooserOpened = true;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Click the button
|
|
116
|
+
const loadButton = page.getByRole('button', { name: /load file/i });
|
|
117
|
+
await loadButton.click();
|
|
118
|
+
|
|
119
|
+
// Wait for the file chooser event to be processed
|
|
120
|
+
await page.waitForEvent('filechooser', { timeout: 5000 }).catch(() => {
|
|
121
|
+
// Event already fired
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Verify file chooser was triggered
|
|
125
|
+
expect(fileChooserOpened).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test.describe('Review Mode', () => {
|
|
130
|
+
test.beforeEach(async ({ page }) => {
|
|
131
|
+
await page.goto('/');
|
|
132
|
+
await expect(page.getByText('Lyrics Correction Review')).toBeVisible();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('should show Review Mode toggle when agentic data is loaded', async ({ page }) => {
|
|
136
|
+
await loadFixtureData(page);
|
|
137
|
+
|
|
138
|
+
// Wait for content to load
|
|
139
|
+
await expect(page.getByText('Hello,')).toBeVisible();
|
|
140
|
+
|
|
141
|
+
// The Review Mode toggle should be visible when agentic corrections are present
|
|
142
|
+
// It will appear as "Review Off" chip initially (only in non-read-only mode with agentic data)
|
|
143
|
+
// Note: In read-only mode, the toggle won't appear
|
|
144
|
+
const reviewChip = page.getByText(/Review Off|Review Mode/i);
|
|
145
|
+
const chipCount = await reviewChip.count();
|
|
146
|
+
|
|
147
|
+
// Log for debugging purposes (will show in test output)
|
|
148
|
+
if (chipCount === 0) {
|
|
149
|
+
// Review toggle only shows in edit mode, not read-only mode
|
|
150
|
+
// This is expected behavior when loading files in read-only mode
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test('should show batch actions panel when Review Mode is enabled', async ({ page }) => {
|
|
155
|
+
await loadFixtureData(page);
|
|
156
|
+
|
|
157
|
+
// Wait for content to load
|
|
158
|
+
await expect(page.getByText('Hello,')).toBeVisible();
|
|
159
|
+
|
|
160
|
+
// Find the Review Mode toggle (only visible in non-read-only mode)
|
|
161
|
+
const reviewToggle = page.getByText(/Review Off/i);
|
|
162
|
+
|
|
163
|
+
if (await reviewToggle.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
164
|
+
await reviewToggle.click();
|
|
165
|
+
|
|
166
|
+
// Wait for the batch actions panel to appear
|
|
167
|
+
await expect(page.getByRole('button', { name: /Accept High Confidence/i })).toBeVisible({ timeout: 5000 });
|
|
168
|
+
await expect(page.getByRole('button', { name: /Accept All/i })).toBeVisible();
|
|
169
|
+
await expect(page.getByRole('button', { name: /Revert All/i })).toBeVisible();
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('should render corrected words with original text preview', async ({ page }) => {
|
|
174
|
+
await loadFixtureData(page);
|
|
175
|
+
|
|
176
|
+
// Wait for transcription content to load
|
|
177
|
+
await expect(page.getByText('Hello,')).toBeVisible();
|
|
178
|
+
|
|
179
|
+
// Verify correction-related content is rendered
|
|
180
|
+
// The corrected word "now" should be visible (from fixture: "you're" -> "now")
|
|
181
|
+
await expect(page.getByText('now')).toBeVisible();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('should toggle Review Mode on and off', async ({ page }) => {
|
|
185
|
+
await loadFixtureData(page);
|
|
186
|
+
|
|
187
|
+
// Wait for content to load
|
|
188
|
+
await expect(page.getByText('Hello,')).toBeVisible();
|
|
189
|
+
|
|
190
|
+
// Find the Review toggle (only visible in non-read-only mode)
|
|
191
|
+
const reviewOff = page.getByText(/Review Off/i);
|
|
192
|
+
|
|
193
|
+
if (await reviewOff.isVisible({ timeout: 2000 }).catch(() => false)) {
|
|
194
|
+
// Click to enable Review Mode
|
|
195
|
+
await reviewOff.click();
|
|
196
|
+
|
|
197
|
+
// Should now show "Review Mode" label (in filled state)
|
|
198
|
+
await expect(page.getByText(/Review Mode/i).first()).toBeVisible();
|
|
199
|
+
|
|
200
|
+
// Click to disable Review Mode
|
|
201
|
+
await page.getByText(/Review Mode/i).first().click();
|
|
202
|
+
|
|
203
|
+
// Should show "Review Off" again
|
|
204
|
+
await expect(page.getByText(/Review Off/i)).toBeVisible();
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
});
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
{
|
|
2
|
+
"original_segments": [
|
|
3
|
+
{
|
|
4
|
+
"id": "seg-1",
|
|
5
|
+
"text": "Hello, is it me you're looking for?",
|
|
6
|
+
"words": [
|
|
7
|
+
{"id": "w1", "text": "Hello,", "start_time": 0.0, "end_time": 0.5},
|
|
8
|
+
{"id": "w2", "text": "is", "start_time": 0.5, "end_time": 0.7},
|
|
9
|
+
{"id": "w3", "text": "it", "start_time": 0.7, "end_time": 0.9},
|
|
10
|
+
{"id": "w4", "text": "me", "start_time": 0.9, "end_time": 1.1},
|
|
11
|
+
{"id": "w5", "text": "you're", "start_time": 1.1, "end_time": 1.3},
|
|
12
|
+
{"id": "w6", "text": "looking", "start_time": 1.3, "end_time": 1.6},
|
|
13
|
+
{"id": "w7", "text": "for?", "start_time": 1.6, "end_time": 1.9}
|
|
14
|
+
],
|
|
15
|
+
"start_time": 0.0,
|
|
16
|
+
"end_time": 1.9
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "seg-2",
|
|
20
|
+
"text": "I can see it in your eyes",
|
|
21
|
+
"words": [
|
|
22
|
+
{"id": "w8", "text": "I", "start_time": 2.0, "end_time": 2.2},
|
|
23
|
+
{"id": "w9", "text": "can", "start_time": 2.2, "end_time": 2.4},
|
|
24
|
+
{"id": "w10", "text": "see", "start_time": 2.4, "end_time": 2.6},
|
|
25
|
+
{"id": "w11", "text": "it", "start_time": 2.6, "end_time": 2.8},
|
|
26
|
+
{"id": "w12", "text": "in", "start_time": 2.8, "end_time": 3.0},
|
|
27
|
+
{"id": "w13", "text": "your", "start_time": 3.0, "end_time": 3.2},
|
|
28
|
+
{"id": "w14", "text": "eyes", "start_time": 3.2, "end_time": 3.5}
|
|
29
|
+
],
|
|
30
|
+
"start_time": 2.0,
|
|
31
|
+
"end_time": 3.5
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "seg-3",
|
|
35
|
+
"text": "I can see it in your smile",
|
|
36
|
+
"words": [
|
|
37
|
+
{"id": "w15", "text": "I", "start_time": 4.0, "end_time": 4.2},
|
|
38
|
+
{"id": "w16", "text": "can", "start_time": 4.2, "end_time": 4.4},
|
|
39
|
+
{"id": "w17", "text": "see", "start_time": 4.4, "end_time": 4.6},
|
|
40
|
+
{"id": "w18", "text": "it", "start_time": 4.6, "end_time": 4.8},
|
|
41
|
+
{"id": "w19", "text": "in", "start_time": 4.8, "end_time": 5.0},
|
|
42
|
+
{"id": "w20", "text": "your", "start_time": 5.0, "end_time": 5.2},
|
|
43
|
+
{"id": "w21", "text": "smile", "start_time": 5.2, "end_time": 5.5}
|
|
44
|
+
],
|
|
45
|
+
"start_time": 4.0,
|
|
46
|
+
"end_time": 5.5
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"reference_lyrics": {
|
|
50
|
+
"genius": {
|
|
51
|
+
"segments": [
|
|
52
|
+
{
|
|
53
|
+
"id": "ref-seg-1",
|
|
54
|
+
"text": "Hello, is it me you're looking for?",
|
|
55
|
+
"words": [
|
|
56
|
+
{"id": "rw1", "text": "Hello,", "start_time": null, "end_time": null},
|
|
57
|
+
{"id": "rw2", "text": "is", "start_time": null, "end_time": null},
|
|
58
|
+
{"id": "rw3", "text": "it", "start_time": null, "end_time": null},
|
|
59
|
+
{"id": "rw4", "text": "me", "start_time": null, "end_time": null},
|
|
60
|
+
{"id": "rw5", "text": "you're", "start_time": null, "end_time": null},
|
|
61
|
+
{"id": "rw6", "text": "looking", "start_time": null, "end_time": null},
|
|
62
|
+
{"id": "rw7", "text": "for?", "start_time": null, "end_time": null}
|
|
63
|
+
],
|
|
64
|
+
"start_time": null,
|
|
65
|
+
"end_time": null
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"metadata": {
|
|
69
|
+
"source": "genius",
|
|
70
|
+
"track_name": "Hello",
|
|
71
|
+
"artist_names": "Lionel Richie",
|
|
72
|
+
"album_name": "Can't Slow Down",
|
|
73
|
+
"duration_ms": 280000,
|
|
74
|
+
"explicit": false,
|
|
75
|
+
"language": "en",
|
|
76
|
+
"is_synced": false,
|
|
77
|
+
"lyrics_provider": "Genius",
|
|
78
|
+
"lyrics_provider_id": "12345",
|
|
79
|
+
"provider_metadata": {}
|
|
80
|
+
},
|
|
81
|
+
"source": "genius"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"anchor_sequences": [
|
|
85
|
+
{
|
|
86
|
+
"id": "anchor-1",
|
|
87
|
+
"transcribed_word_ids": ["w1", "w2", "w3", "w4"],
|
|
88
|
+
"transcription_position": 0,
|
|
89
|
+
"reference_positions": {"genius": 0},
|
|
90
|
+
"reference_word_ids": {"genius": ["rw1", "rw2", "rw3", "rw4"]},
|
|
91
|
+
"confidence": 0.95
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"gap_sequences": [
|
|
95
|
+
{
|
|
96
|
+
"id": "gap-1",
|
|
97
|
+
"transcribed_word_ids": ["w5", "w6", "w7"],
|
|
98
|
+
"transcription_position": 4,
|
|
99
|
+
"preceding_anchor_id": "anchor-1",
|
|
100
|
+
"following_anchor_id": null,
|
|
101
|
+
"reference_word_ids": {"genius": ["rw5", "rw6", "rw7"]}
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"resized_segments": [],
|
|
105
|
+
"corrections_made": 3,
|
|
106
|
+
"confidence": 0.85,
|
|
107
|
+
"corrections": [
|
|
108
|
+
{
|
|
109
|
+
"id": "corr-1",
|
|
110
|
+
"handler": "AgenticCorrector",
|
|
111
|
+
"original_word": "you're",
|
|
112
|
+
"corrected_word": "now",
|
|
113
|
+
"segment_id": "seg-1",
|
|
114
|
+
"word_id": "w5",
|
|
115
|
+
"corrected_word_id": "cw5",
|
|
116
|
+
"source": "genius",
|
|
117
|
+
"confidence": 0.92,
|
|
118
|
+
"reason": "Transcription error - misheard word, reference lyrics confirm it should be 'now' [SOUND_ALIKE] (confidence: 92%)",
|
|
119
|
+
"alternatives": {"your": 0.65},
|
|
120
|
+
"is_deletion": false,
|
|
121
|
+
"split_index": null,
|
|
122
|
+
"split_total": null,
|
|
123
|
+
"reference_positions": {"genius": 4},
|
|
124
|
+
"length": 1
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": "corr-2",
|
|
128
|
+
"handler": "AgenticCorrector",
|
|
129
|
+
"original_word": "it",
|
|
130
|
+
"corrected_word": "",
|
|
131
|
+
"segment_id": "seg-2",
|
|
132
|
+
"word_id": "w11",
|
|
133
|
+
"corrected_word_id": null,
|
|
134
|
+
"source": "genius",
|
|
135
|
+
"confidence": 0.88,
|
|
136
|
+
"reason": "Extra filler word detected, not in reference lyrics [EXTRA_WORDS] (confidence: 88%)",
|
|
137
|
+
"alternatives": {},
|
|
138
|
+
"is_deletion": true,
|
|
139
|
+
"split_index": null,
|
|
140
|
+
"split_total": null,
|
|
141
|
+
"reference_positions": {},
|
|
142
|
+
"length": 1
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"id": "corr-3",
|
|
146
|
+
"handler": "AgenticCorrector",
|
|
147
|
+
"original_word": "I",
|
|
148
|
+
"corrected_word": "",
|
|
149
|
+
"segment_id": "seg-3",
|
|
150
|
+
"word_id": "w15",
|
|
151
|
+
"corrected_word_id": null,
|
|
152
|
+
"source": "genius",
|
|
153
|
+
"confidence": 0.75,
|
|
154
|
+
"reason": "Extra word at start of line, not in reference [EXTRA_WORDS] (confidence: 75%)",
|
|
155
|
+
"alternatives": {},
|
|
156
|
+
"is_deletion": true,
|
|
157
|
+
"split_index": null,
|
|
158
|
+
"split_total": null,
|
|
159
|
+
"reference_positions": {},
|
|
160
|
+
"length": 1
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
"corrected_segments": [
|
|
164
|
+
{
|
|
165
|
+
"id": "seg-1",
|
|
166
|
+
"text": "Hello, is it me you're looking for?",
|
|
167
|
+
"words": [
|
|
168
|
+
{"id": "w1", "text": "Hello,", "start_time": 0.0, "end_time": 0.5},
|
|
169
|
+
{"id": "w2", "text": "is", "start_time": 0.5, "end_time": 0.7},
|
|
170
|
+
{"id": "w3", "text": "it", "start_time": 0.7, "end_time": 0.9},
|
|
171
|
+
{"id": "w4", "text": "me", "start_time": 0.9, "end_time": 1.1},
|
|
172
|
+
{"id": "cw5", "text": "now", "start_time": 1.1, "end_time": 1.3, "created_during_correction": true},
|
|
173
|
+
{"id": "w6", "text": "looking", "start_time": 1.3, "end_time": 1.6},
|
|
174
|
+
{"id": "w7", "text": "for?", "start_time": 1.6, "end_time": 1.9}
|
|
175
|
+
],
|
|
176
|
+
"start_time": 0.0,
|
|
177
|
+
"end_time": 1.9
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "seg-2",
|
|
181
|
+
"text": "I can see in your eyes",
|
|
182
|
+
"words": [
|
|
183
|
+
{"id": "w8", "text": "I", "start_time": 2.0, "end_time": 2.2},
|
|
184
|
+
{"id": "w9", "text": "can", "start_time": 2.2, "end_time": 2.4},
|
|
185
|
+
{"id": "w10", "text": "see", "start_time": 2.4, "end_time": 2.6},
|
|
186
|
+
{"id": "w12", "text": "in", "start_time": 2.8, "end_time": 3.0},
|
|
187
|
+
{"id": "w13", "text": "your", "start_time": 3.0, "end_time": 3.2},
|
|
188
|
+
{"id": "w14", "text": "eyes", "start_time": 3.2, "end_time": 3.5}
|
|
189
|
+
],
|
|
190
|
+
"start_time": 2.0,
|
|
191
|
+
"end_time": 3.5
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "seg-3",
|
|
195
|
+
"text": "can see it in your smile",
|
|
196
|
+
"words": [
|
|
197
|
+
{"id": "w16", "text": "can", "start_time": 4.2, "end_time": 4.4},
|
|
198
|
+
{"id": "w17", "text": "see", "start_time": 4.4, "end_time": 4.6},
|
|
199
|
+
{"id": "w18", "text": "it", "start_time": 4.6, "end_time": 4.8},
|
|
200
|
+
{"id": "w19", "text": "in", "start_time": 4.8, "end_time": 5.0},
|
|
201
|
+
{"id": "w20", "text": "your", "start_time": 5.0, "end_time": 5.2},
|
|
202
|
+
{"id": "w21", "text": "smile", "start_time": 5.2, "end_time": 5.5}
|
|
203
|
+
],
|
|
204
|
+
"start_time": 4.0,
|
|
205
|
+
"end_time": 5.5
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"metadata": {
|
|
209
|
+
"anchor_sequences_count": 1,
|
|
210
|
+
"gap_sequences_count": 1,
|
|
211
|
+
"total_words": 21,
|
|
212
|
+
"correction_ratio": 0.143,
|
|
213
|
+
"audio_filepath": "/path/to/test-audio.mp3",
|
|
214
|
+
"audio_hash": "test-audio-hash-123",
|
|
215
|
+
"available_handlers": [
|
|
216
|
+
{"id": "agentic", "name": "AgenticCorrector", "description": "AI-powered agentic correction", "enabled": true},
|
|
217
|
+
{"id": "sound_alike", "name": "SoundAlikeHandler", "description": "Fixes sound-alike errors", "enabled": true}
|
|
218
|
+
],
|
|
219
|
+
"enabled_handlers": ["AgenticCorrector", "SoundAlikeHandler"]
|
|
220
|
+
},
|
|
221
|
+
"correction_steps": [],
|
|
222
|
+
"word_id_map": {
|
|
223
|
+
"w5": "cw5"
|
|
224
|
+
},
|
|
225
|
+
"segment_id_map": {}
|
|
226
|
+
}
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
"lint": "eslint .",
|
|
12
12
|
"preview": "vite preview",
|
|
13
13
|
"predeploy": "npm run build-prod",
|
|
14
|
-
"deploy": "gh-pages -d dist"
|
|
14
|
+
"deploy": "gh-pages -d dist",
|
|
15
|
+
"test": "playwright test",
|
|
16
|
+
"test:ui": "playwright test --ui",
|
|
17
|
+
"test:headed": "playwright test --headed"
|
|
15
18
|
},
|
|
16
19
|
"dependencies": {
|
|
17
20
|
"@emotion/react": "^11.14.0",
|