karaoke-gen 0.105.4__py3-none-any.whl → 0.107.0__py3-none-any.whl

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 (322) hide show
  1. backend/api/routes/users.py +14 -3
  2. backend/config.py +3 -0
  3. backend/services/encoding_interface.py +4 -0
  4. backend/services/job_notification_service.py +4 -21
  5. backend/tests/test_job_notification_service.py +24 -58
  6. backend/tests/test_video_worker_orchestrator.py +189 -0
  7. backend/workers/video_worker_orchestrator.py +7 -0
  8. karaoke_gen/instrumental_review/server.py +145 -35
  9. karaoke_gen/nextjs_frontend/__init__.py +98 -0
  10. karaoke_gen/nextjs_frontend/out/404/index.html +1 -0
  11. karaoke_gen/nextjs_frontend/out/404.html +1 -0
  12. karaoke_gen/nextjs_frontend/out/__next.__PAGE__.txt +9 -0
  13. karaoke_gen/nextjs_frontend/out/__next._full.txt +22 -0
  14. karaoke_gen/nextjs_frontend/out/__next._head.txt +8 -0
  15. karaoke_gen/nextjs_frontend/out/__next._index.txt +9 -0
  16. karaoke_gen/nextjs_frontend/out/__next._tree.txt +2 -0
  17. karaoke_gen/nextjs_frontend/out/_next/static/chunks/01a7f8fe40f1ff47.js +1 -0
  18. karaoke_gen/nextjs_frontend/out/_next/static/chunks/112f346e31f991df.js +4 -0
  19. karaoke_gen/nextjs_frontend/out/_next/static/chunks/16d1a4dd9d8a873a.js +3 -0
  20. karaoke_gen/nextjs_frontend/out/_next/static/chunks/1ab85c362b8b0e86.js +9 -0
  21. karaoke_gen/nextjs_frontend/out/_next/static/chunks/247eb132b7f7b574.js +1 -0
  22. karaoke_gen/nextjs_frontend/out/_next/static/chunks/2b80d15cc95e4818.js +1 -0
  23. karaoke_gen/nextjs_frontend/out/_next/static/chunks/32c7eba5cd46c1bc.js +7 -0
  24. karaoke_gen/nextjs_frontend/out/_next/static/chunks/483f26794eae53d0.js +1 -0
  25. karaoke_gen/nextjs_frontend/out/_next/static/chunks/550c3b02e85f196a.js +1 -0
  26. karaoke_gen/nextjs_frontend/out/_next/static/chunks/55c5ade44387bef8.js +1 -0
  27. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5628d92b5893add2.css +1 -0
  28. karaoke_gen/nextjs_frontend/out/_next/static/chunks/56ebf7665e4341c8.js +7 -0
  29. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5997132b61dec430.js +1 -0
  30. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5ea55255bce3eb9e.js +5 -0
  31. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5eda89a57490b3cd.js +1 -0
  32. karaoke_gen/nextjs_frontend/out/_next/static/chunks/692f5d9e0d700c76.js +3 -0
  33. karaoke_gen/nextjs_frontend/out/_next/static/chunks/71d7a05b14f9f0f4.js +1 -0
  34. karaoke_gen/nextjs_frontend/out/_next/static/chunks/81ac355749ef3302.js +1 -0
  35. karaoke_gen/nextjs_frontend/out/_next/static/chunks/95f7e5934dbb0e5d.js +1 -0
  36. karaoke_gen/nextjs_frontend/out/_next/static/chunks/9bce8f19eaa46940.js +1 -0
  37. karaoke_gen/nextjs_frontend/out/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  38. karaoke_gen/nextjs_frontend/out/_next/static/chunks/a9ed54eed3e14c92.js +2 -0
  39. karaoke_gen/nextjs_frontend/out/_next/static/chunks/b35cd41238ecfb17.js +1 -0
  40. karaoke_gen/nextjs_frontend/out/_next/static/chunks/b5bc3c3d5ebd49eb.js +1 -0
  41. karaoke_gen/nextjs_frontend/out/_next/static/chunks/b5c078c08db5ae32.js +5 -0
  42. karaoke_gen/nextjs_frontend/out/_next/static/chunks/be9c44a178104187.js +1 -0
  43. karaoke_gen/nextjs_frontend/out/_next/static/chunks/c4c840e18cb4861c.js +1 -0
  44. karaoke_gen/nextjs_frontend/out/_next/static/chunks/c645af7d6b65f73e.js +1 -0
  45. karaoke_gen/nextjs_frontend/out/_next/static/chunks/d2c5e2575df784d4.js +1 -0
  46. karaoke_gen/nextjs_frontend/out/_next/static/chunks/d30af02b96d81462.js +1 -0
  47. karaoke_gen/nextjs_frontend/out/_next/static/chunks/d9bdf64f4ec1e9b7.js +7 -0
  48. karaoke_gen/nextjs_frontend/out/_next/static/chunks/dcde6ed684dacd0e.js +5 -0
  49. karaoke_gen/nextjs_frontend/out/_next/static/chunks/e422cbe931246000.js +1 -0
  50. karaoke_gen/nextjs_frontend/out/_next/static/chunks/e483af34fc792d38.js +1 -0
  51. karaoke_gen/nextjs_frontend/out/_next/static/chunks/e57422aad6b897da.js +1 -0
  52. karaoke_gen/nextjs_frontend/out/_next/static/chunks/ef02697fb404726a.js +1 -0
  53. karaoke_gen/nextjs_frontend/out/_next/static/chunks/ff1a16fafef87110.js +1 -0
  54. karaoke_gen/nextjs_frontend/out/_next/static/chunks/turbopack-2d9ca3017a9deedf.js +3 -0
  55. karaoke_gen/nextjs_frontend/out/_next/static/zpw_-rjFIDV5tlPPtnvRI/_buildManifest.js +11 -0
  56. karaoke_gen/nextjs_frontend/out/_next/static/zpw_-rjFIDV5tlPPtnvRI/_clientMiddlewareManifest.json +1 -0
  57. karaoke_gen/nextjs_frontend/out/_next/static/zpw_-rjFIDV5tlPPtnvRI/_ssgManifest.js +1 -0
  58. karaoke_gen/nextjs_frontend/out/_not-found/__next._full.txt +18 -0
  59. karaoke_gen/nextjs_frontend/out/_not-found/__next._head.txt +8 -0
  60. karaoke_gen/nextjs_frontend/out/_not-found/__next._index.txt +9 -0
  61. karaoke_gen/nextjs_frontend/out/_not-found/__next._not-found.__PAGE__.txt +5 -0
  62. karaoke_gen/nextjs_frontend/out/_not-found/__next._not-found.txt +4 -0
  63. karaoke_gen/nextjs_frontend/out/_not-found/__next._tree.txt +2 -0
  64. karaoke_gen/nextjs_frontend/out/_not-found/index.html +1 -0
  65. karaoke_gen/nextjs_frontend/out/_not-found/index.txt +18 -0
  66. karaoke_gen/nextjs_frontend/out/admin/__next._full.txt +25 -0
  67. karaoke_gen/nextjs_frontend/out/admin/__next._head.txt +8 -0
  68. karaoke_gen/nextjs_frontend/out/admin/__next._index.txt +9 -0
  69. karaoke_gen/nextjs_frontend/out/admin/__next._tree.txt +2 -0
  70. karaoke_gen/nextjs_frontend/out/admin/__next.admin.__PAGE__.txt +9 -0
  71. karaoke_gen/nextjs_frontend/out/admin/__next.admin.txt +7 -0
  72. karaoke_gen/nextjs_frontend/out/admin/beta/__next._full.txt +25 -0
  73. karaoke_gen/nextjs_frontend/out/admin/beta/__next._head.txt +8 -0
  74. karaoke_gen/nextjs_frontend/out/admin/beta/__next._index.txt +9 -0
  75. karaoke_gen/nextjs_frontend/out/admin/beta/__next._tree.txt +2 -0
  76. karaoke_gen/nextjs_frontend/out/admin/beta/__next.admin.beta.__PAGE__.txt +9 -0
  77. karaoke_gen/nextjs_frontend/out/admin/beta/__next.admin.beta.txt +4 -0
  78. karaoke_gen/nextjs_frontend/out/admin/beta/__next.admin.txt +7 -0
  79. karaoke_gen/nextjs_frontend/out/admin/beta/index.html +1 -0
  80. karaoke_gen/nextjs_frontend/out/admin/beta/index.txt +25 -0
  81. karaoke_gen/nextjs_frontend/out/admin/index.html +1 -0
  82. karaoke_gen/nextjs_frontend/out/admin/index.txt +25 -0
  83. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._full.txt +25 -0
  84. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._head.txt +8 -0
  85. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._index.txt +9 -0
  86. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._tree.txt +2 -0
  87. karaoke_gen/nextjs_frontend/out/admin/jobs/__next.admin.jobs.__PAGE__.txt +9 -0
  88. karaoke_gen/nextjs_frontend/out/admin/jobs/__next.admin.jobs.txt +4 -0
  89. karaoke_gen/nextjs_frontend/out/admin/jobs/__next.admin.txt +7 -0
  90. karaoke_gen/nextjs_frontend/out/admin/jobs/index.html +1 -0
  91. karaoke_gen/nextjs_frontend/out/admin/jobs/index.txt +25 -0
  92. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._full.txt +25 -0
  93. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._head.txt +8 -0
  94. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._index.txt +9 -0
  95. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._tree.txt +2 -0
  96. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next.admin.rate-limits.__PAGE__.txt +9 -0
  97. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next.admin.rate-limits.txt +4 -0
  98. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next.admin.txt +7 -0
  99. karaoke_gen/nextjs_frontend/out/admin/rate-limits/index.html +1 -0
  100. karaoke_gen/nextjs_frontend/out/admin/rate-limits/index.txt +25 -0
  101. karaoke_gen/nextjs_frontend/out/admin/searches/__next._full.txt +25 -0
  102. karaoke_gen/nextjs_frontend/out/admin/searches/__next._head.txt +8 -0
  103. karaoke_gen/nextjs_frontend/out/admin/searches/__next._index.txt +9 -0
  104. karaoke_gen/nextjs_frontend/out/admin/searches/__next._tree.txt +2 -0
  105. karaoke_gen/nextjs_frontend/out/admin/searches/__next.admin.searches.__PAGE__.txt +9 -0
  106. karaoke_gen/nextjs_frontend/out/admin/searches/__next.admin.searches.txt +4 -0
  107. karaoke_gen/nextjs_frontend/out/admin/searches/__next.admin.txt +7 -0
  108. karaoke_gen/nextjs_frontend/out/admin/searches/index.html +1 -0
  109. karaoke_gen/nextjs_frontend/out/admin/searches/index.txt +25 -0
  110. karaoke_gen/nextjs_frontend/out/admin/users/__next._full.txt +25 -0
  111. karaoke_gen/nextjs_frontend/out/admin/users/__next._head.txt +8 -0
  112. karaoke_gen/nextjs_frontend/out/admin/users/__next._index.txt +9 -0
  113. karaoke_gen/nextjs_frontend/out/admin/users/__next._tree.txt +2 -0
  114. karaoke_gen/nextjs_frontend/out/admin/users/__next.admin.txt +7 -0
  115. karaoke_gen/nextjs_frontend/out/admin/users/__next.admin.users.__PAGE__.txt +9 -0
  116. karaoke_gen/nextjs_frontend/out/admin/users/__next.admin.users.txt +4 -0
  117. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._full.txt +25 -0
  118. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._head.txt +8 -0
  119. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._index.txt +9 -0
  120. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._tree.txt +2 -0
  121. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.txt +7 -0
  122. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.users.detail.__PAGE__.txt +9 -0
  123. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.users.detail.txt +4 -0
  124. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.users.txt +4 -0
  125. karaoke_gen/nextjs_frontend/out/admin/users/detail/index.html +1 -0
  126. karaoke_gen/nextjs_frontend/out/admin/users/detail/index.txt +25 -0
  127. karaoke_gen/nextjs_frontend/out/admin/users/index.html +1 -0
  128. karaoke_gen/nextjs_frontend/out/admin/users/index.txt +25 -0
  129. karaoke_gen/nextjs_frontend/out/app/__next._full.txt +22 -0
  130. karaoke_gen/nextjs_frontend/out/app/__next._head.txt +8 -0
  131. karaoke_gen/nextjs_frontend/out/app/__next._index.txt +9 -0
  132. karaoke_gen/nextjs_frontend/out/app/__next._tree.txt +2 -0
  133. karaoke_gen/nextjs_frontend/out/app/__next.app.__PAGE__.txt +9 -0
  134. karaoke_gen/nextjs_frontend/out/app/__next.app.txt +4 -0
  135. karaoke_gen/nextjs_frontend/out/app/index.html +1 -0
  136. karaoke_gen/nextjs_frontend/out/app/index.txt +22 -0
  137. karaoke_gen/nextjs_frontend/out/app/jobs/__next._full.txt +19 -0
  138. karaoke_gen/nextjs_frontend/out/app/jobs/__next._head.txt +8 -0
  139. karaoke_gen/nextjs_frontend/out/app/jobs/__next._index.txt +9 -0
  140. karaoke_gen/nextjs_frontend/out/app/jobs/__next._tree.txt +2 -0
  141. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.jobs.$oc$slug.__PAGE__.txt +6 -0
  142. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.jobs.$oc$slug.txt +4 -0
  143. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.jobs.txt +4 -0
  144. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.txt +4 -0
  145. karaoke_gen/nextjs_frontend/out/app/jobs/index.html +1 -0
  146. karaoke_gen/nextjs_frontend/out/app/jobs/index.txt +19 -0
  147. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._full.txt +19 -0
  148. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._head.txt +8 -0
  149. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._index.txt +9 -0
  150. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._tree.txt +2 -0
  151. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.jobs.$oc$slug.__PAGE__.txt +6 -0
  152. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.jobs.$oc$slug.txt +4 -0
  153. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.jobs.txt +4 -0
  154. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.txt +4 -0
  155. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/index.html +1 -0
  156. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/index.txt +19 -0
  157. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._full.txt +19 -0
  158. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._head.txt +8 -0
  159. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._index.txt +9 -0
  160. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._tree.txt +2 -0
  161. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.jobs.$oc$slug.__PAGE__.txt +6 -0
  162. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.jobs.$oc$slug.txt +4 -0
  163. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.jobs.txt +4 -0
  164. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.txt +4 -0
  165. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/index.html +1 -0
  166. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/index.txt +19 -0
  167. karaoke_gen/nextjs_frontend/out/auth/verify/__next._full.txt +22 -0
  168. karaoke_gen/nextjs_frontend/out/auth/verify/__next._head.txt +8 -0
  169. karaoke_gen/nextjs_frontend/out/auth/verify/__next._index.txt +9 -0
  170. karaoke_gen/nextjs_frontend/out/auth/verify/__next._tree.txt +2 -0
  171. karaoke_gen/nextjs_frontend/out/auth/verify/__next.auth.txt +4 -0
  172. karaoke_gen/nextjs_frontend/out/auth/verify/__next.auth.verify.__PAGE__.txt +9 -0
  173. karaoke_gen/nextjs_frontend/out/auth/verify/__next.auth.verify.txt +4 -0
  174. karaoke_gen/nextjs_frontend/out/auth/verify/index.html +1 -0
  175. karaoke_gen/nextjs_frontend/out/auth/verify/index.txt +22 -0
  176. karaoke_gen/nextjs_frontend/out/index.html +1 -0
  177. karaoke_gen/nextjs_frontend/out/index.txt +22 -0
  178. karaoke_gen/nextjs_frontend/out/manifest.webmanifest +31 -0
  179. karaoke_gen/nextjs_frontend/out/order/success/__next._full.txt +22 -0
  180. karaoke_gen/nextjs_frontend/out/order/success/__next._head.txt +8 -0
  181. karaoke_gen/nextjs_frontend/out/order/success/__next._index.txt +9 -0
  182. karaoke_gen/nextjs_frontend/out/order/success/__next._tree.txt +2 -0
  183. karaoke_gen/nextjs_frontend/out/order/success/__next.order.success.__PAGE__.txt +9 -0
  184. karaoke_gen/nextjs_frontend/out/order/success/__next.order.success.txt +4 -0
  185. karaoke_gen/nextjs_frontend/out/order/success/__next.order.txt +4 -0
  186. karaoke_gen/nextjs_frontend/out/order/success/index.html +1 -0
  187. karaoke_gen/nextjs_frontend/out/order/success/index.txt +22 -0
  188. karaoke_gen/nextjs_frontend/out/payment/success/__next._full.txt +22 -0
  189. karaoke_gen/nextjs_frontend/out/payment/success/__next._head.txt +8 -0
  190. karaoke_gen/nextjs_frontend/out/payment/success/__next._index.txt +9 -0
  191. karaoke_gen/nextjs_frontend/out/payment/success/__next._tree.txt +2 -0
  192. karaoke_gen/nextjs_frontend/out/payment/success/__next.payment.success.__PAGE__.txt +9 -0
  193. karaoke_gen/nextjs_frontend/out/payment/success/__next.payment.success.txt +4 -0
  194. karaoke_gen/nextjs_frontend/out/payment/success/__next.payment.txt +4 -0
  195. karaoke_gen/nextjs_frontend/out/payment/success/index.html +1 -0
  196. karaoke_gen/nextjs_frontend/out/payment/success/index.txt +22 -0
  197. karaoke_gen/nextjs_frontend/out/screenshots/email-action_reminder.png +0 -0
  198. karaoke_gen/nextjs_frontend/out/screenshots/email-beta_welcome.png +0 -0
  199. karaoke_gen/nextjs_frontend/out/screenshots/email-job_completion.png +0 -0
  200. karaoke_gen/nextjs_frontend/out/screenshots/example-output.avif +0 -0
  201. karaoke_gen/nextjs_frontend/out/screenshots/homepage-full.png +0 -0
  202. karaoke_gen/nextjs_frontend/out/screenshots/homepage-hero.png +0 -0
  203. karaoke_gen/nextjs_frontend/out/screenshots/instrumental-review.avif +0 -0
  204. karaoke_gen/nextjs_frontend/out/screenshots/instrumental-review.png +0 -0
  205. karaoke_gen/nextjs_frontend/out/screenshots/job-dashboard.avif +0 -0
  206. karaoke_gen/nextjs_frontend/out/screenshots/lyrics-review.avif +0 -0
  207. karaoke_gen/nextjs_frontend/out/screenshots/lyrics-review.png +0 -0
  208. karaoke_gen/nextjs_frontend/out/sw.js +183 -0
  209. karaoke_gen/utils/cli_args.py +3 -3
  210. karaoke_gen/utils/gen_cli.py +4 -0
  211. karaoke_gen/utils/remote_cli.py +8 -40
  212. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/METADATA +1 -1
  213. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/RECORD +227 -121
  214. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/WHEEL +1 -1
  215. lyrics_transcriber/correction/agentic/agent.py +83 -60
  216. lyrics_transcriber/correction/anchor_sequence.py +48 -3
  217. lyrics_transcriber/correction/corrector.py +92 -58
  218. lyrics_transcriber/review/server.py +165 -33
  219. lyrics_transcriber/utils/tracing.py +214 -0
  220. karaoke_gen/instrumental_review/static/index.html +0 -1721
  221. lyrics_transcriber/frontend/.gitignore +0 -24
  222. lyrics_transcriber/frontend/.yarn/releases/yarn-4.7.0.cjs +0 -935
  223. lyrics_transcriber/frontend/.yarnrc.yml +0 -3
  224. lyrics_transcriber/frontend/README.md +0 -50
  225. lyrics_transcriber/frontend/REPLACE_ALL_FUNCTIONALITY.md +0 -210
  226. lyrics_transcriber/frontend/__init__.py +0 -25
  227. lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts +0 -207
  228. lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json +0 -226
  229. lyrics_transcriber/frontend/eslint.config.js +0 -28
  230. lyrics_transcriber/frontend/index.html +0 -22
  231. lyrics_transcriber/frontend/package-lock.json +0 -4553
  232. lyrics_transcriber/frontend/package.json +0 -48
  233. lyrics_transcriber/frontend/playwright.config.ts +0 -69
  234. lyrics_transcriber/frontend/public/android-chrome-192x192.png +0 -0
  235. lyrics_transcriber/frontend/public/android-chrome-512x512.png +0 -0
  236. lyrics_transcriber/frontend/src/App.tsx +0 -243
  237. lyrics_transcriber/frontend/src/api.ts +0 -262
  238. lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +0 -111
  239. lyrics_transcriber/frontend/src/components/AddLyricsModal.tsx +0 -114
  240. lyrics_transcriber/frontend/src/components/AgenticCorrectionMetrics.tsx +0 -204
  241. lyrics_transcriber/frontend/src/components/AppHeader.tsx +0 -65
  242. lyrics_transcriber/frontend/src/components/AudioPlayer.tsx +0 -180
  243. lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +0 -175
  244. lyrics_transcriber/frontend/src/components/CorrectionAnnotationModal.tsx +0 -359
  245. lyrics_transcriber/frontend/src/components/CorrectionDetailCard.tsx +0 -281
  246. lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx +0 -162
  247. lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +0 -257
  248. lyrics_transcriber/frontend/src/components/EditActionBar.tsx +0 -94
  249. lyrics_transcriber/frontend/src/components/EditModal.tsx +0 -720
  250. lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx +0 -592
  251. lyrics_transcriber/frontend/src/components/EditWordList.tsx +0 -431
  252. lyrics_transcriber/frontend/src/components/FileUpload.tsx +0 -77
  253. lyrics_transcriber/frontend/src/components/FindReplaceModal.tsx +0 -467
  254. lyrics_transcriber/frontend/src/components/Header.tsx +0 -520
  255. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +0 -1526
  256. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +0 -216
  257. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +0 -721
  258. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx +0 -80
  259. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +0 -999
  260. lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx +0 -51
  261. lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx +0 -127
  262. lyrics_transcriber/frontend/src/components/ModeSelector.tsx +0 -67
  263. lyrics_transcriber/frontend/src/components/ModelSelector.tsx +0 -23
  264. lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx +0 -177
  265. lyrics_transcriber/frontend/src/components/ReferenceView.tsx +0 -268
  266. lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx +0 -336
  267. lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +0 -354
  268. lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx +0 -64
  269. lyrics_transcriber/frontend/src/components/TimelineEditor.tsx +0 -383
  270. lyrics_transcriber/frontend/src/components/TimingOffsetModal.tsx +0 -131
  271. lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +0 -266
  272. lyrics_transcriber/frontend/src/components/WordDivider.tsx +0 -191
  273. lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +0 -466
  274. lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx +0 -56
  275. lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +0 -89
  276. lyrics_transcriber/frontend/src/components/shared/constants.ts +0 -30
  277. lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +0 -180
  278. lyrics_transcriber/frontend/src/components/shared/styles.ts +0 -13
  279. lyrics_transcriber/frontend/src/components/shared/types.js +0 -2
  280. lyrics_transcriber/frontend/src/components/shared/types.ts +0 -135
  281. lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts +0 -177
  282. lyrics_transcriber/frontend/src/components/shared/utils/localStorage.ts +0 -78
  283. lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts +0 -75
  284. lyrics_transcriber/frontend/src/components/shared/utils/segmentOperations.ts +0 -360
  285. lyrics_transcriber/frontend/src/components/shared/utils/timingUtils.ts +0 -110
  286. lyrics_transcriber/frontend/src/components/shared/utils/wordUtils.ts +0 -22
  287. lyrics_transcriber/frontend/src/hooks/useManualSync.ts +0 -537
  288. lyrics_transcriber/frontend/src/main.tsx +0 -11
  289. lyrics_transcriber/frontend/src/theme.ts +0 -406
  290. lyrics_transcriber/frontend/src/types/global.d.ts +0 -9
  291. lyrics_transcriber/frontend/src/types.js +0 -2
  292. lyrics_transcriber/frontend/src/types.ts +0 -199
  293. lyrics_transcriber/frontend/src/validation.ts +0 -132
  294. lyrics_transcriber/frontend/src/vite-env.d.ts +0 -1
  295. lyrics_transcriber/frontend/tsconfig.app.json +0 -26
  296. lyrics_transcriber/frontend/tsconfig.json +0 -25
  297. lyrics_transcriber/frontend/tsconfig.node.json +0 -23
  298. lyrics_transcriber/frontend/tsconfig.tsbuildinfo +0 -1
  299. lyrics_transcriber/frontend/update_version.js +0 -11
  300. lyrics_transcriber/frontend/vite.config.d.ts +0 -2
  301. lyrics_transcriber/frontend/vite.config.js +0 -15
  302. lyrics_transcriber/frontend/vite.config.ts +0 -16
  303. lyrics_transcriber/frontend/web_assets/android-chrome-192x192.png +0 -0
  304. lyrics_transcriber/frontend/web_assets/android-chrome-512x512.png +0 -0
  305. lyrics_transcriber/frontend/web_assets/apple-touch-icon.png +0 -0
  306. lyrics_transcriber/frontend/web_assets/assets/index-BSMgOq4Z.js +0 -44465
  307. lyrics_transcriber/frontend/web_assets/assets/index-BSMgOq4Z.js.map +0 -1
  308. lyrics_transcriber/frontend/web_assets/favicon-16x16.png +0 -0
  309. lyrics_transcriber/frontend/web_assets/favicon-32x32.png +0 -0
  310. lyrics_transcriber/frontend/web_assets/favicon.ico +0 -0
  311. lyrics_transcriber/frontend/web_assets/index.html +0 -22
  312. lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.png +0 -0
  313. lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.svg +0 -5
  314. lyrics_transcriber/frontend/yarn.lock +0 -3711
  315. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/apple-touch-icon.png +0 -0
  316. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/favicon-16x16.png +0 -0
  317. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/favicon-32x32.png +0 -0
  318. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/favicon.ico +0 -0
  319. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/nomad-karaoke-logo.svg +0 -0
  320. /lyrics_transcriber/frontend/public/nomad-karaoke-logo.png → /karaoke_gen/nextjs_frontend/out/nomad-logo.png +0 -0
  321. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/entry_points.txt +0 -0
  322. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,175 +0,0 @@
1
- import { Box, IconButton, Tooltip, useMediaQuery, useTheme } from '@mui/material'
2
- import UndoIcon from '@mui/icons-material/Undo'
3
- import EditIcon from '@mui/icons-material/Edit'
4
- import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'
5
- import { COLORS } from './shared/constants'
6
- import { styled } from '@mui/material/styles'
7
-
8
- interface CorrectionInfo {
9
- originalWord: string
10
- handler: string
11
- confidence: number
12
- source: string
13
- reason?: string
14
- }
15
-
16
- interface CorrectedWordWithActionsProps {
17
- word: string
18
- originalWord: string
19
- correction: CorrectionInfo
20
- onRevert: () => void
21
- onEdit: () => void
22
- onAccept: () => void
23
- onClick?: () => void
24
- backgroundColor?: string
25
- shouldFlash?: boolean
26
- showActions?: boolean // Controls whether inline action buttons are visible
27
- }
28
-
29
- const WordContainer = styled(Box, {
30
- shouldForwardProp: (prop) => !['shouldFlash'].includes(prop as string)
31
- })<{ shouldFlash?: boolean }>(({ shouldFlash }) => ({
32
- display: 'inline-flex',
33
- alignItems: 'center',
34
- gap: '2px',
35
- padding: '1px 3px',
36
- borderRadius: '2px',
37
- cursor: 'pointer',
38
- position: 'relative',
39
- backgroundColor: COLORS.corrected,
40
- animation: shouldFlash ? 'flash 1s ease-in-out infinite' : 'none',
41
- '@keyframes flash': {
42
- '0%, 100%': { opacity: 1 },
43
- '50%': { opacity: 0.5 }
44
- },
45
- '&:hover': {
46
- backgroundColor: 'rgba(34, 197, 94, 0.35)' // green tint hover - works for both modes
47
- }
48
- }))
49
-
50
- const OriginalWordLabel = styled(Box)(({ theme }) => ({
51
- position: 'absolute',
52
- top: '-14px',
53
- left: '0',
54
- fontSize: '0.6rem',
55
- color: theme.palette.text.secondary, // Theme-aware text color
56
- textDecoration: 'line-through',
57
- opacity: 0.7,
58
- whiteSpace: 'nowrap',
59
- pointerEvents: 'none'
60
- }))
61
-
62
- const ActionsContainer = styled(Box)({
63
- display: 'inline-flex',
64
- alignItems: 'center',
65
- gap: '1px',
66
- marginLeft: '2px'
67
- })
68
-
69
- const ActionButton = styled(IconButton)(({ theme }) => ({
70
- padding: '2px',
71
- minWidth: '20px',
72
- minHeight: '20px',
73
- width: '20px',
74
- height: '20px',
75
- backgroundColor: theme.palette.mode === 'dark'
76
- ? 'rgba(30, 41, 59, 0.9)' // slate-800 with opacity for dark mode
77
- : 'rgba(241, 245, 249, 0.9)', // slate-100 for light mode
78
- border: `1px solid ${theme.palette.divider}`,
79
- '&:hover': {
80
- backgroundColor: theme.palette.mode === 'dark'
81
- ? 'rgba(51, 65, 85, 1)' // slate-700 for dark mode
82
- : 'rgba(226, 232, 240, 1)', // slate-200 for light mode
83
- transform: 'scale(1.1)'
84
- },
85
- '& .MuiSvgIcon-root': {
86
- fontSize: '0.875rem'
87
- },
88
- // Ensure minimum touch target on mobile
89
- [theme.breakpoints.down('sm')]: {
90
- minWidth: '28px',
91
- minHeight: '28px',
92
- width: '28px',
93
- height: '28px',
94
- padding: '4px'
95
- }
96
- }))
97
-
98
- export default function CorrectedWordWithActions({
99
- word,
100
- originalWord,
101
- onRevert,
102
- onEdit,
103
- onAccept,
104
- onClick,
105
- backgroundColor,
106
- shouldFlash,
107
- showActions = true
108
- }: CorrectedWordWithActionsProps) {
109
- const theme = useTheme()
110
- const isMobile = useMediaQuery(theme.breakpoints.down('sm'))
111
-
112
- const handleAction = (e: React.MouseEvent, action: () => void) => {
113
- e.stopPropagation()
114
- action()
115
- }
116
-
117
- return (
118
- <WordContainer
119
- shouldFlash={shouldFlash}
120
- sx={{ backgroundColor: backgroundColor || COLORS.corrected }}
121
- onClick={onClick}
122
- >
123
- <OriginalWordLabel>{originalWord}</OriginalWordLabel>
124
-
125
- <Box
126
- component="span"
127
- sx={{
128
- fontSize: '0.85rem',
129
- lineHeight: 1.2,
130
- fontWeight: 600
131
- }}
132
- >
133
- {word}
134
- </Box>
135
-
136
- {showActions && (
137
- <ActionsContainer>
138
- <Tooltip title="Revert to original" placement="top" arrow>
139
- <ActionButton
140
- size="small"
141
- onClick={(e) => handleAction(e, onRevert)}
142
- aria-label="revert correction"
143
- >
144
- <UndoIcon />
145
- </ActionButton>
146
- </Tooltip>
147
-
148
- <Tooltip title="Edit correction" placement="top" arrow>
149
- <ActionButton
150
- size="small"
151
- onClick={(e) => handleAction(e, onEdit)}
152
- aria-label="edit correction"
153
- >
154
- <EditIcon />
155
- </ActionButton>
156
- </Tooltip>
157
-
158
- {!isMobile && (
159
- <Tooltip title="Accept correction" placement="top" arrow>
160
- <ActionButton
161
- size="small"
162
- onClick={(e) => handleAction(e, onAccept)}
163
- aria-label="accept correction"
164
- sx={{ color: 'success.main' }}
165
- >
166
- <CheckCircleOutlineIcon />
167
- </ActionButton>
168
- </Tooltip>
169
- )}
170
- </ActionsContainer>
171
- )}
172
- </WordContainer>
173
- )
174
- }
175
-
@@ -1,359 +0,0 @@
1
- import { useState, useEffect } from 'react'
2
- import {
3
- Dialog,
4
- DialogTitle,
5
- DialogContent,
6
- DialogActions,
7
- Button,
8
- FormControl,
9
- InputLabel,
10
- Select,
11
- MenuItem,
12
- TextField,
13
- Slider,
14
- Typography,
15
- Box,
16
- Paper,
17
- Chip,
18
- Alert,
19
- SelectChangeEvent
20
- } from '@mui/material'
21
- import { CorrectionAnnotation, CorrectionAnnotationType, CorrectionAction } from '../types'
22
-
23
- interface CorrectionAnnotationModalProps {
24
- open: boolean
25
- onClose: () => void
26
- onSave: (annotation: Omit<CorrectionAnnotation, 'annotation_id' | 'timestamp'>) => void
27
- onSkip: () => void
28
- // Context about the correction being made
29
- originalText: string
30
- correctedText: string
31
- wordIdsAffected: string[]
32
- // Optional: What the AI suggested
33
- agenticProposal?: {
34
- action: string
35
- replacement_text?: string
36
- confidence: number
37
- reason: string
38
- gap_category?: string
39
- }
40
- // Reference lyrics that were consulted
41
- referenceSources: string[]
42
- // Song metadata
43
- audioHash: string
44
- artist: string
45
- title: string
46
- sessionId: string
47
- gapId?: string
48
- }
49
-
50
- const ANNOTATION_TYPES: { value: CorrectionAnnotationType; label: string; description: string }[] = [
51
- {
52
- value: 'SOUND_ALIKE' as CorrectionAnnotationType,
53
- label: 'Sound-Alike Error',
54
- description: 'Homophones or similar-sounding words (e.g., "out" vs "now")'
55
- },
56
- {
57
- value: 'BACKGROUND_VOCALS' as CorrectionAnnotationType,
58
- label: 'Background Vocals',
59
- description: 'Backing vocals that should be removed from karaoke'
60
- },
61
- {
62
- value: 'EXTRA_WORDS' as CorrectionAnnotationType,
63
- label: 'Extra Filler Words',
64
- description: 'Transcription added words like "And", "But", "Well"'
65
- },
66
- {
67
- value: 'PUNCTUATION_ONLY' as CorrectionAnnotationType,
68
- label: 'Punctuation/Style Only',
69
- description: 'Only punctuation or capitalization differences'
70
- },
71
- {
72
- value: 'REPEATED_SECTION' as CorrectionAnnotationType,
73
- label: 'Repeated Section',
74
- description: 'Chorus or verse repetition not in condensed references'
75
- },
76
- {
77
- value: 'COMPLEX_MULTI_ERROR' as CorrectionAnnotationType,
78
- label: 'Complex Multi-Error',
79
- description: 'Multiple different error types in one section'
80
- },
81
- {
82
- value: 'AMBIGUOUS' as CorrectionAnnotationType,
83
- label: 'Ambiguous',
84
- description: 'Unclear without listening to audio'
85
- },
86
- {
87
- value: 'NO_ERROR' as CorrectionAnnotationType,
88
- label: 'No Error',
89
- description: 'Transcription matches at least one reference source'
90
- },
91
- {
92
- value: 'MANUAL_EDIT' as CorrectionAnnotationType,
93
- label: 'Manual Edit',
94
- description: 'Human-initiated correction not from detected gap'
95
- }
96
- ]
97
-
98
- const CONFIDENCE_LABELS: { [key: number]: string } = {
99
- 1: '1 - Very Uncertain',
100
- 2: '2 - Somewhat Uncertain',
101
- 3: '3 - Neutral',
102
- 4: '4 - Fairly Confident',
103
- 5: '5 - Very Confident'
104
- }
105
-
106
- export default function CorrectionAnnotationModal({
107
- open,
108
- onClose,
109
- onSave,
110
- onSkip,
111
- originalText,
112
- correctedText,
113
- wordIdsAffected,
114
- agenticProposal,
115
- referenceSources,
116
- audioHash,
117
- artist,
118
- title,
119
- sessionId,
120
- gapId
121
- }: CorrectionAnnotationModalProps) {
122
- const [annotationType, setAnnotationType] = useState<CorrectionAnnotationType>('MANUAL_EDIT' as CorrectionAnnotationType)
123
- const [actionTaken, setActionTaken] = useState<CorrectionAction>('REPLACE' as CorrectionAction)
124
- const [confidence, setConfidence] = useState<number>(3)
125
- const [reasoning, setReasoning] = useState<string>('')
126
- const [agenticAgreed, setAgenticAgreed] = useState<boolean>(false)
127
- const [error, setError] = useState<string>('')
128
-
129
- // Pre-fill if we have an agentic proposal
130
- useEffect(() => {
131
- if (agenticProposal && agenticProposal.gap_category) {
132
- setAnnotationType(agenticProposal.gap_category as CorrectionAnnotationType)
133
- // Check if human correction matches AI suggestion
134
- const agreed = agenticProposal.replacement_text
135
- ? correctedText.toLowerCase().includes(agenticProposal.replacement_text.toLowerCase())
136
- : false
137
- setAgenticAgreed(agreed)
138
- }
139
- }, [agenticProposal, correctedText])
140
-
141
- // Determine action type based on correction
142
- useEffect(() => {
143
- if (originalText === correctedText) {
144
- setActionTaken('NO_ACTION' as CorrectionAction)
145
- } else if (correctedText === '') {
146
- setActionTaken('DELETE' as CorrectionAction)
147
- } else if (originalText === '') {
148
- setActionTaken('INSERT' as CorrectionAction)
149
- } else {
150
- setActionTaken('REPLACE' as CorrectionAction)
151
- }
152
- }, [originalText, correctedText])
153
-
154
- const handleSave = () => {
155
- // Validate
156
- if (reasoning.length < 10) {
157
- setError('Reasoning must be at least 10 characters')
158
- return
159
- }
160
-
161
- const annotation: Omit<CorrectionAnnotation, 'annotation_id' | 'timestamp'> = {
162
- audio_hash: audioHash,
163
- gap_id: gapId || null,
164
- annotation_type: annotationType,
165
- action_taken: actionTaken,
166
- original_text: originalText,
167
- corrected_text: correctedText,
168
- confidence,
169
- reasoning,
170
- word_ids_affected: wordIdsAffected,
171
- agentic_proposal: agenticProposal || null,
172
- agentic_category: agenticProposal?.gap_category || null,
173
- agentic_agreed: agenticAgreed,
174
- reference_sources_consulted: referenceSources,
175
- artist,
176
- title,
177
- session_id: sessionId
178
- }
179
-
180
- onSave(annotation)
181
- handleClose()
182
- }
183
-
184
- const handleClose = () => {
185
- // Reset form
186
- setAnnotationType('MANUAL_EDIT' as CorrectionAnnotationType)
187
- setConfidence(3)
188
- setReasoning('')
189
- setError('')
190
- setAgenticAgreed(false)
191
- onClose()
192
- }
193
-
194
- const handleSkipAndClose = () => {
195
- handleClose()
196
- onSkip()
197
- }
198
-
199
- return (
200
- <Dialog
201
- open={open}
202
- onClose={handleClose}
203
- maxWidth="md"
204
- fullWidth
205
- >
206
- <DialogTitle>
207
- <Typography variant="h6">Annotate Your Correction</Typography>
208
- <Typography variant="caption" color="text.secondary">
209
- Help improve the AI by explaining your correction
210
- </Typography>
211
- </DialogTitle>
212
-
213
- <DialogContent dividers>
214
- {/* Show what changed */}
215
- <Paper elevation={0} sx={{ p: 2, mb: 3, bgcolor: 'grey.50' }}>
216
- <Typography variant="subtitle2" gutterBottom>
217
- Your Correction:
218
- </Typography>
219
- <Box sx={{ display: 'flex', gap: 2, alignItems: 'center' }}>
220
- <Box sx={{ flex: 1 }}>
221
- <Typography variant="caption" color="error">Original:</Typography>
222
- <Typography
223
- sx={{
224
- textDecoration: 'line-through',
225
- color: 'error.main',
226
- fontFamily: 'monospace'
227
- }}
228
- >
229
- {originalText || '(empty)'}
230
- </Typography>
231
- </Box>
232
- <Typography variant="h6">→</Typography>
233
- <Box sx={{ flex: 1 }}>
234
- <Typography variant="caption" color="success.main">Corrected:</Typography>
235
- <Typography
236
- sx={{
237
- color: 'success.main',
238
- fontWeight: 'bold',
239
- fontFamily: 'monospace'
240
- }}
241
- >
242
- {correctedText || '(empty)'}
243
- </Typography>
244
- </Box>
245
- </Box>
246
- </Paper>
247
-
248
- {/* Show AI suggestion if available */}
249
- {agenticProposal && (
250
- <Alert
251
- severity={agenticAgreed ? "success" : "info"}
252
- sx={{ mb: 3 }}
253
- >
254
- <Typography variant="subtitle2" gutterBottom>
255
- AI Suggestion:
256
- </Typography>
257
- <Typography variant="body2">
258
- Category: <strong>{agenticProposal.gap_category}</strong>
259
- </Typography>
260
- <Typography variant="body2">
261
- Action: <strong>{agenticProposal.action}</strong>
262
- {agenticProposal.replacement_text && ` → "${agenticProposal.replacement_text}"`}
263
- </Typography>
264
- <Typography variant="body2">
265
- Reason: {agenticProposal.reason}
266
- </Typography>
267
- <Typography variant="body2" sx={{ mt: 1 }}>
268
- {agenticAgreed
269
- ? '✓ Your correction matches the AI suggestion'
270
- : '✗ Your correction differs from the AI suggestion'}
271
- </Typography>
272
- </Alert>
273
- )}
274
-
275
- {/* Reference sources */}
276
- {referenceSources.length > 0 && (
277
- <Box sx={{ mb: 3 }}>
278
- <Typography variant="subtitle2" gutterBottom>
279
- Reference Sources Consulted:
280
- </Typography>
281
- <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
282
- {referenceSources.map(source => (
283
- <Chip key={source} label={source} size="small" />
284
- ))}
285
- </Box>
286
- </Box>
287
- )}
288
-
289
- {/* Annotation type */}
290
- <FormControl fullWidth sx={{ mb: 3 }}>
291
- <InputLabel>Correction Type *</InputLabel>
292
- <Select
293
- value={annotationType}
294
- label="Correction Type *"
295
- onChange={(e: SelectChangeEvent) => setAnnotationType(e.target.value as CorrectionAnnotationType)}
296
- >
297
- {ANNOTATION_TYPES.map(type => (
298
- <MenuItem key={type.value} value={type.value}>
299
- <Box>
300
- <Typography variant="body1">{type.label}</Typography>
301
- <Typography variant="caption" color="text.secondary">
302
- {type.description}
303
- </Typography>
304
- </Box>
305
- </MenuItem>
306
- ))}
307
- </Select>
308
- </FormControl>
309
-
310
- {/* Confidence slider */}
311
- <Box sx={{ mb: 3 }}>
312
- <Typography variant="subtitle2" gutterBottom>
313
- Confidence in Your Correction *
314
- </Typography>
315
- <Slider
316
- value={confidence}
317
- onChange={(_, newValue) => setConfidence(newValue as number)}
318
- min={1}
319
- max={5}
320
- step={1}
321
- marks
322
- valueLabelDisplay="auto"
323
- valueLabelFormat={(value) => CONFIDENCE_LABELS[value]}
324
- />
325
- <Typography variant="caption" color="text.secondary">
326
- {CONFIDENCE_LABELS[confidence]}
327
- </Typography>
328
- </Box>
329
-
330
- {/* Reasoning text area */}
331
- <TextField
332
- fullWidth
333
- multiline
334
- rows={4}
335
- label="Reasoning *"
336
- placeholder="Explain why this correction is needed (minimum 10 characters)..."
337
- value={reasoning}
338
- onChange={(e) => {
339
- setReasoning(e.target.value)
340
- setError('')
341
- }}
342
- error={!!error}
343
- helperText={error || `${reasoning.length}/10 minimum characters`}
344
- required
345
- />
346
- </DialogContent>
347
-
348
- <DialogActions>
349
- <Button onClick={handleSkipAndClose} color="inherit">
350
- Skip
351
- </Button>
352
- <Button onClick={handleSave} variant="contained" color="primary">
353
- Save & Continue
354
- </Button>
355
- </DialogActions>
356
- </Dialog>
357
- )
358
- }
359
-