karaoke-gen 0.76.28__tar.gz → 0.92.0__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.
Files changed (300) hide show
  1. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/PKG-INFO +6 -1
  2. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/static/index.html +2 -2
  3. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/lyrics_processor.py +9 -5
  4. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/style_loader.py +3 -1
  5. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/video_background_processor.py +9 -4
  6. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/core/controller.py +16 -5
  7. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/agent.py +19 -7
  8. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/langfuse_integration.py +208 -0
  9. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/prompts/__init__.py +25 -0
  10. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/prompts/classifier.py +66 -6
  11. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/prompts/langfuse_prompts.py +298 -0
  12. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/config.py +27 -4
  13. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/constants.py +1 -1
  14. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/langchain_bridge.py +75 -20
  15. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/model_factory.py +69 -13
  16. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/response_parser.py +18 -6
  17. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/router.py +40 -0
  18. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/corrector.py +227 -170
  19. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/operations.py +24 -9
  20. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/package.json +1 -1
  21. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.tsbuildinfo +1 -0
  22. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/vite.config.js +5 -0
  23. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/assets/index-BECn1o8Q.js → karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/assets/index-V91xgc4E.js +6109 -5341
  24. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/assets/index-V91xgc4E.js.map +1 -0
  25. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/index.html +6 -2
  26. karaoke_gen-0.92.0/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.svg +5 -0
  27. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/generator.py +17 -3
  28. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/video.py +30 -5
  29. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/pyproject.toml +7 -1
  30. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/langfuse_integration.py +0 -35
  31. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/prompts/__init__.py +0 -2
  32. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/router.py +0 -35
  33. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/llm.py +0 -293
  34. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/llm_providers.py +0 -60
  35. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.tsbuildinfo +0 -1
  36. karaoke_gen-0.76.28/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/assets/index-BECn1o8Q.js.map +0 -1
  37. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/LICENSE +0 -0
  38. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/README.md +0 -0
  39. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/__init__.py +0 -0
  40. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/audio_fetcher.py +0 -0
  41. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/audio_processor.py +0 -0
  42. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/config.py +0 -0
  43. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/file_handler.py +0 -0
  44. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/__init__.py +0 -0
  45. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/analyzer.py +0 -0
  46. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/editor.py +0 -0
  47. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/models.py +0 -0
  48. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/server.py +0 -0
  49. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/instrumental_review/waveform.py +0 -0
  50. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/karaoke_finalise/__init__.py +0 -0
  51. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/karaoke_finalise/karaoke_finalise.py +0 -0
  52. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/karaoke_gen.py +0 -0
  53. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/metadata.py +0 -0
  54. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/__init__.py +0 -0
  55. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/base.py +0 -0
  56. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/context.py +0 -0
  57. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/executors/__init__.py +0 -0
  58. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/executors/local.py +0 -0
  59. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/executors/remote.py +0 -0
  60. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/stages/__init__.py +0 -0
  61. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/stages/finalize.py +0 -0
  62. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/stages/render.py +0 -0
  63. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/stages/screens.py +0 -0
  64. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/stages/separation.py +0 -0
  65. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/pipeline/stages/transcription.py +0 -0
  66. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/resources/AvenirNext-Bold.ttf +0 -0
  67. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/resources/Montserrat-Bold.ttf +0 -0
  68. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/resources/Oswald-Bold.ttf +0 -0
  69. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/resources/Oswald-SemiBold.ttf +0 -0
  70. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/resources/Zurich_Cn_BT_Bold.ttf +0 -0
  71. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/utils/__init__.py +0 -0
  72. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/utils/bulk_cli.py +0 -0
  73. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/utils/cli_args.py +0 -0
  74. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/utils/gen_cli.py +0 -0
  75. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/utils/remote_cli.py +0 -0
  76. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/karaoke_gen/video_generator.py +0 -0
  77. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/__init__.py +0 -0
  78. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/cli/__init__.py +0 -0
  79. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/cli/cli_main.py +0 -0
  80. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/core/__init__.py +0 -0
  81. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/core/config.py +0 -0
  82. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/__init__.py +0 -0
  83. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/__init__.py +0 -0
  84. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/adapter.py +0 -0
  85. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/aggregator.py +0 -0
  86. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/collector.py +0 -0
  87. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/retention.py +0 -0
  88. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/feedback/store.py +0 -0
  89. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/__init__.py +0 -0
  90. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/ambiguous.py +0 -0
  91. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/background_vocals.py +0 -0
  92. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/base.py +0 -0
  93. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/complex_multi_error.py +0 -0
  94. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/extra_words.py +0 -0
  95. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/no_error.py +0 -0
  96. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/punctuation.py +0 -0
  97. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/registry.py +0 -0
  98. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/repeated_section.py +0 -0
  99. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/handlers/sound_alike.py +0 -0
  100. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/__init__.py +0 -0
  101. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/ai_correction.py +0 -0
  102. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/correction_session.py +0 -0
  103. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/enums.py +0 -0
  104. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/human_feedback.py +0 -0
  105. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/learning_data.py +0 -0
  106. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/observability_metrics.py +0 -0
  107. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/schemas.py +0 -0
  108. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/models/utils.py +0 -0
  109. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/__init__.py +0 -0
  110. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/metrics.py +0 -0
  111. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/observability/performance.py +0 -0
  112. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/__init__.py +0 -0
  113. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/base.py +0 -0
  114. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/circuit_breaker.py +0 -0
  115. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/health.py +0 -0
  116. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/response_cache.py +0 -0
  117. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/providers/retry_executor.py +0 -0
  118. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/__init__.py +0 -0
  119. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/consensus_workflow.py +0 -0
  120. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/correction_graph.py +0 -0
  121. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/agentic/workflows/feedback_workflow.py +0 -0
  122. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/anchor_sequence.py +0 -0
  123. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/feedback/__init__.py +0 -0
  124. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/feedback/schemas.py +0 -0
  125. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/feedback/store.py +0 -0
  126. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/__init__.py +0 -0
  127. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/base.py +0 -0
  128. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/extend_anchor.py +0 -0
  129. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/levenshtein.py +0 -0
  130. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/no_space_punct_match.py +0 -0
  131. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/relaxed_word_count_match.py +0 -0
  132. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/repeat.py +0 -0
  133. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/sound_alike.py +0 -0
  134. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/syllables_match.py +0 -0
  135. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/word_count_match.py +0 -0
  136. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/handlers/word_operations.py +0 -0
  137. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/phrase_analyzer.py +0 -0
  138. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/correction/text_utils.py +0 -0
  139. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/.gitignore +0 -0
  140. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/.yarn/releases/yarn-4.7.0.cjs +0 -0
  141. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/.yarnrc.yml +0 -0
  142. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/README.md +0 -0
  143. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/REPLACE_ALL_FUNCTIONALITY.md +0 -0
  144. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/__init__.py +0 -0
  145. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts +0 -0
  146. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json +0 -0
  147. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/eslint.config.js +0 -0
  148. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/index.html +0 -0
  149. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/package-lock.json +0 -0
  150. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/playwright.config.ts +0 -0
  151. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/android-chrome-192x192.png +0 -0
  152. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/android-chrome-512x512.png +0 -0
  153. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/apple-touch-icon.png +0 -0
  154. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/favicon-16x16.png +0 -0
  155. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/favicon-32x32.png +0 -0
  156. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/favicon.ico +0 -0
  157. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/nomad-karaoke-logo.png +0 -0
  158. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg +0 -0
  159. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/App.tsx +0 -0
  160. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/api.ts +0 -0
  161. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +0 -0
  162. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AddLyricsModal.tsx +0 -0
  163. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AgenticCorrectionMetrics.tsx +0 -0
  164. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AppHeader.tsx +0 -0
  165. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/AudioPlayer.tsx +0 -0
  166. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +0 -0
  167. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectionAnnotationModal.tsx +0 -0
  168. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectionDetailCard.tsx +0 -0
  169. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx +0 -0
  170. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +0 -0
  171. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditActionBar.tsx +0 -0
  172. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditModal.tsx +0 -0
  173. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx +0 -0
  174. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/EditWordList.tsx +0 -0
  175. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/FileUpload.tsx +0 -0
  176. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/FindReplaceModal.tsx +0 -0
  177. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/Header.tsx +0 -0
  178. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +0 -0
  179. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +0 -0
  180. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +0 -0
  181. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx +0 -0
  182. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +0 -0
  183. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx +0 -0
  184. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx +0 -0
  185. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ModeSelector.tsx +0 -0
  186. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ModelSelector.tsx +0 -0
  187. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx +0 -0
  188. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ReferenceView.tsx +0 -0
  189. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx +0 -0
  190. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +0 -0
  191. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx +0 -0
  192. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/TimelineEditor.tsx +0 -0
  193. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/TimingOffsetModal.tsx +0 -0
  194. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +0 -0
  195. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/WordDivider.tsx +0 -0
  196. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +0 -0
  197. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx +0 -0
  198. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +0 -0
  199. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/constants.ts +0 -0
  200. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +0 -0
  201. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/styles.ts +0 -0
  202. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/types.js +0 -0
  203. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/types.ts +0 -0
  204. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts +0 -0
  205. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/localStorage.ts +0 -0
  206. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts +0 -0
  207. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/segmentOperations.ts +0 -0
  208. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/timingUtils.ts +0 -0
  209. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/components/shared/utils/wordUtils.ts +0 -0
  210. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/hooks/useManualSync.ts +0 -0
  211. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/main.tsx +0 -0
  212. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/theme.ts +0 -0
  213. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/types/global.d.ts +0 -0
  214. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/types.js +0 -0
  215. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/types.ts +0 -0
  216. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/validation.ts +0 -0
  217. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/src/vite-env.d.ts +0 -0
  218. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.app.json +0 -0
  219. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.json +0 -0
  220. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/tsconfig.node.json +0 -0
  221. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/update_version.js +0 -0
  222. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/vite.config.d.ts +0 -0
  223. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/vite.config.ts +0 -0
  224. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/android-chrome-192x192.png +0 -0
  225. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/android-chrome-512x512.png +0 -0
  226. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/apple-touch-icon.png +0 -0
  227. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/favicon-16x16.png +0 -0
  228. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/favicon-32x32.png +0 -0
  229. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/favicon.ico +0 -0
  230. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.png +0 -0
  231. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/frontend/yarn.lock +0 -0
  232. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/__init__.py +0 -0
  233. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/base_lyrics_provider.py +0 -0
  234. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/file_provider.py +0 -0
  235. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/genius.py +0 -0
  236. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/lrclib.py +0 -0
  237. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/musixmatch.py +0 -0
  238. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/spotify.py +0 -0
  239. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/lyrics/user_input_provider.py +0 -0
  240. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/__init__.py +0 -0
  241. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/__init__.py +0 -0
  242. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/ass.py +0 -0
  243. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/ass_specs.txt +0 -0
  244. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/config.py +0 -0
  245. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/constants.py +0 -0
  246. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/event.py +0 -0
  247. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/formatters.py +0 -0
  248. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/lyrics_line.py +0 -0
  249. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/lyrics_screen.py +0 -0
  250. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/section_detector.py +0 -0
  251. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/section_screen.py +0 -0
  252. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/ass/style.py +0 -0
  253. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdg.py +0 -0
  254. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/__init__.py +0 -0
  255. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/cdg.py +0 -0
  256. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/composer.py +0 -0
  257. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/config.py +0 -0
  258. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/images/instrumental.png +0 -0
  259. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/images/intro.png +0 -0
  260. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/pack.py +0 -0
  261. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/render.py +0 -0
  262. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/centertexttoplogobottomtext.png +0 -0
  263. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/circlein.png +0 -0
  264. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/circleout.png +0 -0
  265. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/fizzle.png +0 -0
  266. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/largecentertexttoplogo.png +0 -0
  267. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/rectangle.png +0 -0
  268. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/spiral.png +0 -0
  269. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/topleftmusicalnotes.png +0 -0
  270. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wipein.png +0 -0
  271. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wipeleft.png +0 -0
  272. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wipeout.png +0 -0
  273. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/transitions/wiperight.png +0 -0
  274. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/cdgmaker/utils.py +0 -0
  275. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/countdown_processor.py +0 -0
  276. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/AvenirNext-Bold.ttf +0 -0
  277. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/DMSans-VariableFont_opsz,wght.ttf +0 -0
  278. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/DMSerifDisplay-Regular.ttf +0 -0
  279. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/Oswald-SemiBold.ttf +0 -0
  280. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/Zurich_Cn_BT_Bold.ttf +0 -0
  281. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/arial.ttf +0 -0
  282. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/georgia.ttf +0 -0
  283. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/fonts/verdana.ttf +0 -0
  284. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/lrc_to_cdg.py +0 -0
  285. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/lyrics_file.py +0 -0
  286. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/plain_text.py +0 -0
  287. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/segment_resizer.py +0 -0
  288. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/output/subtitles.py +0 -0
  289. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/review/__init__.py +0 -0
  290. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/review/server.py +0 -0
  291. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/storage/__init__.py +0 -0
  292. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/storage/dropbox.py +0 -0
  293. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/__init__.py +0 -0
  294. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/audioshake.py +0 -0
  295. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/base_transcriber.py +0 -0
  296. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/local_whisper.py +0 -0
  297. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/transcribers/whisper.py +0 -0
  298. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/types.py +0 -0
  299. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/lyrics_transcriber_temp/lyrics_transcriber/utils/__init__.py +0 -0
  300. {karaoke_gen-0.76.28 → karaoke_gen-0.92.0}/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.76.28
3
+ Version: 0.92.0
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
@@ -14,12 +14,14 @@ Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Provides-Extra: local-whisper
17
+ Requires-Dist: aiohttp (>=3.13.2,<4.0.0)
17
18
  Requires-Dist: argparse (>=1.4.0)
18
19
  Requires-Dist: attrs (>=24.2.0)
19
20
  Requires-Dist: audio-separator[cpu] (>=0.34.0)
20
21
  Requires-Dist: beautifulsoup4 (>=4)
21
22
  Requires-Dist: cattrs (>=24.1.2)
22
23
  Requires-Dist: dropbox (>=12)
24
+ Requires-Dist: email-validator (>=2.0.0)
23
25
  Requires-Dist: fastapi (>=0.104.0)
24
26
  Requires-Dist: fetch-lyrics-from-genius (>=0.1)
25
27
  Requires-Dist: ffmpeg-python (>=0.2.0,<0.3.0)
@@ -41,6 +43,7 @@ Requires-Dist: kbputils (>=0.0.16,<0.0.17)
41
43
  Requires-Dist: langchain (>=0.3.0)
42
44
  Requires-Dist: langchain-anthropic (>=0.2.0)
43
45
  Requires-Dist: langchain-core (>=0.3.0)
46
+ Requires-Dist: langchain-google-genai (>=2.0.0)
44
47
  Requires-Dist: langchain-ollama (>=0.2.0)
45
48
  Requires-Dist: langchain-openai (>=0.2.0)
46
49
  Requires-Dist: langfuse (>=3.0.0)
@@ -75,10 +78,12 @@ Requires-Dist: python-levenshtein (>=0.26)
75
78
  Requires-Dist: python-multipart (>=0.0.20,<0.0.21)
76
79
  Requires-Dist: python-slugify (>=8)
77
80
  Requires-Dist: requests (>=2)
81
+ Requires-Dist: sendgrid (>=6.10.0)
78
82
  Requires-Dist: shortuuid (>=1.0.13)
79
83
  Requires-Dist: spacy (>=3.8.7)
80
84
  Requires-Dist: spacy-syllables (>=3)
81
85
  Requires-Dist: srsly (>=2.5.1)
86
+ Requires-Dist: stripe (>=7.0.0)
82
87
  Requires-Dist: syllables (>=1)
83
88
  Requires-Dist: syrics (>=0)
84
89
  Requires-Dist: thefuzz (>=0.22)
@@ -786,8 +786,8 @@
786
786
 
787
787
  if (waveformRes.ok) {
788
788
  waveformData = await waveformRes.json();
789
- // API returns duration_seconds, not duration
790
- duration = waveformData.duration_seconds || 0;
789
+ // API may return duration_seconds (cloud) or duration (local)
790
+ duration = waveformData.duration_seconds || waveformData.duration || 0;
791
791
  }
792
792
 
793
793
  // Set initial selection based on recommendation
@@ -3,6 +3,7 @@ import re
3
3
  import logging
4
4
  import shutil
5
5
  import json
6
+ from typing import Optional
6
7
  from lyrics_transcriber import LyricsTranscriber, OutputConfig, TranscriberConfig, LyricsConfig
7
8
  from lyrics_transcriber.core.controller import LyricsControllerResult
8
9
  from dotenv import load_dotenv
@@ -252,10 +253,11 @@ class LyricsProcessor:
252
253
  "See README.md 'Transcription Providers' section for detailed setup instructions."
253
254
  )
254
255
 
255
- def transcribe_lyrics(self, input_audio_wav, artist, title, track_output_dir, lyrics_artist=None, lyrics_title=None):
256
+ def transcribe_lyrics(self, input_audio_wav, artist, title, track_output_dir, lyrics_artist=None, lyrics_title=None,
257
+ agentic_deadline: Optional[float] = None):
256
258
  """
257
259
  Transcribe lyrics for a track.
258
-
260
+
259
261
  Args:
260
262
  input_audio_wav: Path to the audio file
261
263
  artist: Original artist name (used for filename generation)
@@ -263,7 +265,9 @@ class LyricsProcessor:
263
265
  track_output_dir: Output directory path
264
266
  lyrics_artist: Artist name for lyrics processing (defaults to artist if None)
265
267
  lyrics_title: Title for lyrics processing (defaults to title if None)
266
-
268
+ agentic_deadline: Optional Unix timestamp. If agentic correction is still
269
+ running after this time, it will abort and return uncorrected results.
270
+
267
271
  Raises:
268
272
  ValueError: If transcription is enabled but no providers are configured
269
273
  """
@@ -423,8 +427,8 @@ class LyricsProcessor:
423
427
  logger=self.logger,
424
428
  )
425
429
 
426
- # Process and get results
427
- results: LyricsControllerResult = transcriber.process()
430
+ # Process and get results (pass deadline for agentic timeout)
431
+ results: LyricsControllerResult = transcriber.process(agentic_deadline=agentic_deadline)
428
432
  self.logger.info(f"Transcriber Results Filepaths:")
429
433
  for key, value in results.__dict__.items():
430
434
  if key.endswith("_filepath"):
@@ -70,7 +70,9 @@ DEFAULT_KARAOKE_STYLE = {
70
70
  "background_color": "#000000",
71
71
  "background_image": None,
72
72
  # Font settings
73
- "font": "Arial",
73
+ # Using "Noto Sans" for full Unicode support (CJK, Arabic, symbols, etc.)
74
+ # Requires fonts-noto-* packages installed in Docker image
75
+ "font": "Noto Sans",
74
76
  "font_path": "", # Must be string, not None (for ASS generator)
75
77
  "ass_name": "Default",
76
78
  # Colors in "R, G, B, A" format (required by ASS)
@@ -156,15 +156,20 @@ class VideoBackgroundProcessor:
156
156
  """
157
157
  Escape a file path for use in ffmpeg filter expressions.
158
158
 
159
+ FFmpeg filter syntax uses single quotes to protect special characters
160
+ like spaces, colons, and semicolons. Single quotes within the path
161
+ are escaped using the '\\'' pattern (end quote, literal quote, start quote).
162
+
159
163
  Args:
160
164
  path: File path to escape
161
165
 
162
166
  Returns:
163
- str: Escaped path
167
+ str: Escaped path (wrapped in single quotes)
164
168
  """
165
- # Escape backslashes and colons for ffmpeg filter syntax
166
- escaped = path.replace("\\", "\\\\").replace(":", "\\:")
167
- return escaped
169
+ # Escape single quotes: ' becomes '\'' (end quote, \', start quote)
170
+ escaped = path.replace("'", "'\\''")
171
+ # Wrap entire path in single quotes
172
+ return f"'{escaped}'"
168
173
 
169
174
  def build_video_filter(self, ass_subtitles_path, darkness_percent, fonts_dir=None):
170
175
  """
@@ -289,8 +289,13 @@ class LyricsTranscriber:
289
289
  """Initialize output generation service."""
290
290
  return OutputGenerator(config=self.output_config, logger=self.logger)
291
291
 
292
- def process(self) -> LyricsControllerResult:
293
- """Main processing method that orchestrates the entire workflow."""
292
+ def process(self, agentic_deadline: Optional[float] = None) -> LyricsControllerResult:
293
+ """Main processing method that orchestrates the entire workflow.
294
+
295
+ Args:
296
+ agentic_deadline: Optional Unix timestamp. If agentic correction is still
297
+ running after this time, it will abort and return uncorrected results.
298
+ """
294
299
 
295
300
  self.logger.info(f"LyricsTranscriber controller beginning processing for {self.artist} - {self.title}")
296
301
 
@@ -390,7 +395,7 @@ class LyricsTranscriber:
390
395
 
391
396
  # Step 3: Process and correct lyrics if enabled AND we have transcription results
392
397
  if self.output_config.run_correction and self.results.transcription_results:
393
- self.correct_lyrics()
398
+ self.correct_lyrics(agentic_deadline=agentic_deadline)
394
399
  elif self.output_config.run_correction:
395
400
  self.logger.info("Skipping lyrics correction - no transcription results available")
396
401
 
@@ -494,8 +499,13 @@ class LyricsTranscriber:
494
499
  else:
495
500
  self.logger.debug(" - LocalWhisper: DISABLED (enable_local_whisper=False)")
496
501
 
497
- def correct_lyrics(self) -> None:
498
- """Run lyrics correction using transcription and internet lyrics."""
502
+ def correct_lyrics(self, agentic_deadline: Optional[float] = None) -> None:
503
+ """Run lyrics correction using transcription and internet lyrics.
504
+
505
+ Args:
506
+ agentic_deadline: Optional Unix timestamp. If agentic correction is still
507
+ running after this time, it will abort and return uncorrected results.
508
+ """
499
509
  self.logger.info("Starting lyrics correction process")
500
510
 
501
511
  # Check if we have reference lyrics to work with
@@ -553,6 +563,7 @@ class LyricsTranscriber:
553
563
  transcription_results=self.results.transcription_results,
554
564
  lyrics_results=self.results.lyrics_results,
555
565
  metadata=metadata,
566
+ agentic_deadline=agentic_deadline,
556
567
  )
557
568
 
558
569
  # Store corrected results
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import logging
4
4
  import os
5
5
  import json
6
+ import time
6
7
  from typing import Dict, Any, List, Optional
7
8
 
8
9
  from .providers.base import BaseAIProvider
@@ -120,7 +121,7 @@ class AgenticCorrector:
120
121
  title: Optional[str] = None
121
122
  ) -> Optional[GapClassification]:
122
123
  """Classify a gap using the AI provider.
123
-
124
+
124
125
  Args:
125
126
  gap_id: Unique identifier for the gap
126
127
  gap_text: The text of the gap
@@ -129,10 +130,13 @@ class AgenticCorrector:
129
130
  reference_contexts: Dictionary of reference lyrics from each source
130
131
  artist: Song artist name
131
132
  title: Song title
132
-
133
+
133
134
  Returns:
134
135
  GapClassification object or None if classification fails
135
136
  """
137
+ logger.info(f"🤖 Classifying gap {gap_id} ({len(gap_text)} chars)")
138
+ start_time = time.time()
139
+
136
140
  # Build classification prompt
137
141
  prompt = build_classification_prompt(
138
142
  gap_text=gap_text,
@@ -143,7 +147,7 @@ class AgenticCorrector:
143
147
  title=title,
144
148
  gap_id=gap_id
145
149
  )
146
-
150
+
147
151
  # Call AI provider to get classification
148
152
  try:
149
153
  data = self._provider.generate_correction_proposals(
@@ -151,17 +155,25 @@ class AgenticCorrector:
151
155
  schema=GapClassification.model_json_schema(),
152
156
  session_id=self._session_id
153
157
  )
154
-
158
+
159
+ elapsed = time.time() - start_time
160
+
155
161
  # Extract first result
156
162
  if data and len(data) > 0:
157
163
  item = data[0]
158
164
  if isinstance(item, dict) and "error" not in item:
159
165
  classification = GapClassification.model_validate(item)
160
- logger.debug(f"🤖 Classified gap {gap_id} as {classification.category} (confidence: {classification.confidence})")
166
+ logger.info(
167
+ f"🤖 Classified gap {gap_id} as {classification.category} "
168
+ f"(confidence: {classification.confidence:.2f}) in {elapsed:.2f}s"
169
+ )
161
170
  return classification
171
+ else:
172
+ logger.warning(f"🤖 Classification returned error for gap {gap_id}: {item}")
162
173
  except Exception as e:
163
- logger.warning(f"🤖 Failed to classify gap {gap_id}: {e}")
164
-
174
+ elapsed = time.time() - start_time
175
+ logger.warning(f"🤖 Failed to classify gap {gap_id} after {elapsed:.2f}s: {e}")
176
+
165
177
  return None
166
178
 
167
179
  def propose_for_gap(
@@ -0,0 +1,208 @@
1
+ """LangFuse integration for agentic correction observability and prompt management.
2
+
3
+ This module provides:
4
+ - Client initialization with fail-fast behavior when configured
5
+ - Metrics recording for observability
6
+ - Prompt fetching for dynamic prompt management
7
+ - Dataset fetching for few-shot examples
8
+ """
9
+
10
+ from typing import Optional, Dict, Any, List
11
+ import os
12
+ import logging
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ # Module-level client singleton
17
+ _langfuse_client: Optional[Any] = None
18
+ _client_initialized: bool = False
19
+
20
+
21
+ class LangFuseConfigError(Exception):
22
+ """Raised when LangFuse is configured but initialization fails."""
23
+ pass
24
+
25
+
26
+ def is_langfuse_configured() -> bool:
27
+ """Check if LangFuse credentials are configured in environment."""
28
+ public_key = os.getenv("LANGFUSE_PUBLIC_KEY")
29
+ secret_key = os.getenv("LANGFUSE_SECRET_KEY")
30
+ return bool(public_key and secret_key)
31
+
32
+
33
+ def setup_langfuse() -> Optional[object]:
34
+ """Initialize Langfuse client if keys are present; return client or None.
35
+
36
+ This avoids hard dependency at import time; caller can check for None and
37
+ no-op if observability is not configured.
38
+
39
+ Note: This function does NOT fail fast - use get_langfuse_client() for
40
+ fail-fast behavior when LangFuse is required.
41
+ """
42
+ secret = os.getenv("LANGFUSE_SECRET_KEY")
43
+ public = os.getenv("LANGFUSE_PUBLIC_KEY")
44
+ host = os.getenv("LANGFUSE_HOST", "https://us.cloud.langfuse.com")
45
+ if not (secret and public):
46
+ return None
47
+ try:
48
+ from langfuse import Langfuse # type: ignore
49
+
50
+ client = Langfuse(secret_key=secret, public_key=public, host=host)
51
+ return client
52
+ except Exception:
53
+ return None
54
+
55
+
56
+ def get_langfuse_client() -> Optional[Any]:
57
+ """Get or create the LangFuse client singleton.
58
+
59
+ Unlike setup_langfuse(), this function implements fail-fast behavior:
60
+ if LangFuse keys are configured but initialization fails, it raises
61
+ an exception rather than returning None.
62
+
63
+ Returns:
64
+ Langfuse client instance, or None if not configured
65
+
66
+ Raises:
67
+ LangFuseConfigError: If keys are set but initialization fails
68
+ """
69
+ global _langfuse_client, _client_initialized
70
+
71
+ if _client_initialized:
72
+ return _langfuse_client
73
+
74
+ secret = os.getenv("LANGFUSE_SECRET_KEY")
75
+ public = os.getenv("LANGFUSE_PUBLIC_KEY")
76
+ host = os.getenv("LANGFUSE_HOST", "https://us.cloud.langfuse.com")
77
+
78
+ if not (secret and public):
79
+ logger.debug("LangFuse keys not configured, client disabled")
80
+ _client_initialized = True
81
+ return None
82
+
83
+ try:
84
+ from langfuse import Langfuse
85
+
86
+ _langfuse_client = Langfuse(
87
+ secret_key=secret,
88
+ public_key=public,
89
+ host=host,
90
+ )
91
+ _client_initialized = True
92
+ logger.info(f"LangFuse client initialized (host: {host})")
93
+ return _langfuse_client
94
+
95
+ except Exception as e:
96
+ # Fail fast - if keys are set, we expect LangFuse to work
97
+ raise LangFuseConfigError(
98
+ f"LangFuse keys are set but initialization failed: {e}\n"
99
+ f"Check:\n"
100
+ f" - LANGFUSE_PUBLIC_KEY: {public[:10] if public else 'not set'}...\n"
101
+ f" - LANGFUSE_SECRET_KEY: {'set' if secret else 'not set'}\n"
102
+ f" - LANGFUSE_HOST: {host}"
103
+ ) from e
104
+
105
+
106
+ def reset_langfuse_client() -> None:
107
+ """Reset the global LangFuse client (for testing)."""
108
+ global _langfuse_client, _client_initialized
109
+ _langfuse_client = None
110
+ _client_initialized = False
111
+
112
+
113
+ def record_metrics(client: Optional[object], name: str, metrics: Dict[str, Any]) -> None:
114
+ """Record custom metrics to Langfuse if initialized."""
115
+ if client is None:
116
+ return
117
+ try:
118
+ # Minimal shape to avoid strict coupling; callers can extend
119
+ client.trace(name=name, metadata=metrics)
120
+ except Exception:
121
+ # Swallow observability errors to never impact core flow
122
+ pass
123
+
124
+
125
+ def fetch_prompt(name: str, client: Optional[Any] = None, label: Optional[str] = "production") -> Any:
126
+ """Fetch a prompt template from LangFuse.
127
+
128
+ Args:
129
+ name: The prompt name in LangFuse
130
+ client: Optional pre-initialized client. If None, uses get_langfuse_client()
131
+ label: Prompt label to fetch (default: "production"). If the labeled version
132
+ is not found, falls back to version 1.
133
+
134
+ Returns:
135
+ LangFuse prompt object
136
+
137
+ Raises:
138
+ LangFuseConfigError: If LangFuse is not configured
139
+ RuntimeError: If prompt fetch fails
140
+ """
141
+ if client is None:
142
+ client = get_langfuse_client()
143
+
144
+ if client is None:
145
+ raise LangFuseConfigError(
146
+ f"Cannot fetch prompt '{name}': LangFuse is not configured. "
147
+ f"Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY."
148
+ )
149
+
150
+ try:
151
+ # Try to fetch with the specified label (default: production)
152
+ prompt = client.get_prompt(name, label=label)
153
+ logger.debug(f"Fetched prompt '{name}' (label={label}) from LangFuse")
154
+ return prompt
155
+ except Exception as label_error:
156
+ # If labeled version not found, try fetching version 1 as fallback
157
+ # This handles newly created prompts that haven't been promoted yet
158
+ try:
159
+ prompt = client.get_prompt(name, version=1)
160
+ logger.warning(
161
+ f"Prompt '{name}' label '{label}' not found, using version 1. "
162
+ f"Consider promoting this prompt in LangFuse UI."
163
+ )
164
+ return prompt
165
+ except Exception as version_error:
166
+ raise RuntimeError(
167
+ f"Failed to fetch prompt '{name}' from LangFuse: "
168
+ f"Label '{label}' error: {label_error}, "
169
+ f"Version 1 fallback error: {version_error}"
170
+ ) from version_error
171
+
172
+
173
+ def fetch_dataset(name: str, client: Optional[Any] = None) -> List[Dict[str, Any]]:
174
+ """Fetch a dataset from LangFuse and return its items.
175
+
176
+ Args:
177
+ name: The dataset name in LangFuse
178
+ client: Optional pre-initialized client. If None, uses get_langfuse_client()
179
+
180
+ Returns:
181
+ List of dataset item inputs (the actual example data)
182
+
183
+ Raises:
184
+ LangFuseConfigError: If LangFuse is not configured
185
+ RuntimeError: If dataset fetch fails
186
+ """
187
+ if client is None:
188
+ client = get_langfuse_client()
189
+
190
+ if client is None:
191
+ raise LangFuseConfigError(
192
+ f"Cannot fetch dataset '{name}': LangFuse is not configured. "
193
+ f"Set LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY."
194
+ )
195
+
196
+ try:
197
+ dataset = client.get_dataset(name)
198
+ items = []
199
+ for item in dataset.items:
200
+ if hasattr(item, 'input') and item.input:
201
+ items.append(item.input)
202
+
203
+ logger.debug(f"Fetched {len(items)} items from dataset '{name}'")
204
+ return items
205
+ except Exception as e:
206
+ raise RuntimeError(
207
+ f"Failed to fetch dataset '{name}' from LangFuse: {e}"
208
+ ) from e
@@ -0,0 +1,25 @@
1
+ """Prompt templates for agentic correction."""
2
+
3
+ from .classifier import (
4
+ build_classification_prompt,
5
+ build_classification_prompt_hardcoded,
6
+ get_hardcoded_examples,
7
+ )
8
+ from .langfuse_prompts import (
9
+ LangFusePromptService,
10
+ LangFusePromptError,
11
+ LangFuseDatasetError,
12
+ get_prompt_service,
13
+ reset_prompt_service,
14
+ )
15
+
16
+ __all__ = [
17
+ "build_classification_prompt",
18
+ "build_classification_prompt_hardcoded",
19
+ "get_hardcoded_examples",
20
+ "LangFusePromptService",
21
+ "LangFusePromptError",
22
+ "LangFuseDatasetError",
23
+ "get_prompt_service",
24
+ "reset_prompt_service",
25
+ ]
@@ -1,23 +1,35 @@
1
- """Gap classification prompt builder for agentic correction."""
1
+ """Gap classification prompt builder for agentic correction.
2
+
3
+ This module provides two modes of operation:
4
+ 1. LangFuse mode: Prompts and examples fetched from LangFuse for dynamic iteration
5
+ 2. Hardcoded mode: Fallback for local development when LangFuse is not configured
6
+
7
+ The main entry point is `build_classification_prompt()` which automatically
8
+ selects the appropriate mode based on LangFuse configuration.
9
+ """
2
10
 
3
11
  from typing import Dict, List, Optional
4
12
  import yaml
5
13
  import os
14
+ import logging
6
15
  from pathlib import Path
7
16
 
17
+ logger = logging.getLogger(__name__)
18
+
8
19
 
9
20
  def load_few_shot_examples() -> Dict[str, List[Dict]]:
10
21
  """Load few-shot examples from examples.yaml if it exists."""
11
22
  examples_path = Path(__file__).parent / "examples.yaml"
12
-
23
+
13
24
  if not examples_path.exists():
14
25
  return get_hardcoded_examples()
15
-
26
+
16
27
  try:
17
28
  with open(examples_path, 'r') as f:
18
29
  data = yaml.safe_load(f)
19
30
  return data.get('examples_by_category', {})
20
- except Exception:
31
+ except Exception as e:
32
+ logger.warning(f"Failed to load examples.yaml, using hardcoded examples: {e}")
21
33
  return get_hardcoded_examples()
22
34
 
23
35
 
@@ -122,7 +134,12 @@ def build_classification_prompt(
122
134
  gap_id: Optional[str] = None
123
135
  ) -> str:
124
136
  """Build a prompt for classifying a gap in the transcription.
125
-
137
+
138
+ This function automatically selects between LangFuse and hardcoded prompts:
139
+ - If LangFuse is configured (LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY set),
140
+ fetches the prompt template and examples from LangFuse.
141
+ - Otherwise, uses hardcoded prompts for local development.
142
+
126
143
  Args:
127
144
  gap_text: The text of the gap that needs classification
128
145
  preceding_words: Text immediately before the gap
@@ -131,7 +148,50 @@ def build_classification_prompt(
131
148
  artist: Song artist name for context
132
149
  title: Song title for context
133
150
  gap_id: Identifier for the gap
134
-
151
+
152
+ Returns:
153
+ Formatted prompt string for the LLM
154
+
155
+ Raises:
156
+ LangFusePromptError: If LangFuse is configured but prompt fetch fails
157
+ """
158
+ from .langfuse_prompts import get_prompt_service
159
+
160
+ service = get_prompt_service()
161
+ return service.get_classification_prompt(
162
+ gap_text=gap_text,
163
+ preceding_words=preceding_words,
164
+ following_words=following_words,
165
+ reference_contexts=reference_contexts,
166
+ artist=artist,
167
+ title=title,
168
+ gap_id=gap_id
169
+ )
170
+
171
+
172
+ def build_classification_prompt_hardcoded(
173
+ gap_text: str,
174
+ preceding_words: str,
175
+ following_words: str,
176
+ reference_contexts: Dict[str, str],
177
+ artist: Optional[str] = None,
178
+ title: Optional[str] = None,
179
+ gap_id: Optional[str] = None
180
+ ) -> str:
181
+ """Build a prompt for classifying a gap using hardcoded templates.
182
+
183
+ This is the fallback implementation used when LangFuse is not configured.
184
+ It is also used as the source of truth for migrating prompts to LangFuse.
185
+
186
+ Args:
187
+ gap_text: The text of the gap that needs classification
188
+ preceding_words: Text immediately before the gap
189
+ following_words: Text immediately after the gap
190
+ reference_contexts: Dictionary of reference lyrics from each source
191
+ artist: Song artist name for context
192
+ title: Song title for context
193
+ gap_id: Identifier for the gap
194
+
135
195
  Returns:
136
196
  Formatted prompt string for the LLM
137
197
  """