Stabilize note generation under provider limits#334
Open
hzsw1234 wants to merge 1 commit into
Open
Conversation
Bilibili/CDP downloads, online ASR, and browser polling can finish out of order or fail under parallel note jobs, so this routes note work through a bounded executor, makes saved result files the source of truth, isolates video-understanding frame output per task, and keeps the frontend polling path from freezing after backend completion. Constraint: Bilibili/CDP and online ASR providers are fragile under high concurrency Constraint: Existing user workflow needs the v2 install isolated from old 8000/3015 services Rejected: Unlimited parallel tasks | likely to trigger 412/rate-limit/provider failures Rejected: Commit runtime Chrome profile/cache | local machine artifact, not source Confidence: high Scope-risk: moderate Directive: Keep NOTE_TASK_MAX_WORKERS conservative unless provider rate limits are revalidated Tested: backend py_compile for note router/service/executor/transcriber/video reader/Bilibili downloader/main Tested: frontend npm run build with NODE_OPTIONS=--max-old-space-size=4096 Tested: /api/task_queue_status returned max_workers=2 active=0 queued=0 on port 18483 Tested: frontend 13015 returned HTTP 200 with Cache-Control=no-store and assets/index-DwU9B8dh.js Tested: git diff --cached --check Not-tested: high concurrency above 2 workers
There was a problem hiding this comment.
Pull request overview
This PR aims to stabilize BiliNote v2 note generation under provider limits by introducing bounded concurrency for note tasks, improving Bilibili download/CDP fallback resilience, and fixing frontend polling/step rendering to avoid “stuck” states.
Changes:
- Backend: add bounded-concurrency task executor, improve task status/result consistency, and harden Bilibili/CDP download + transcript fallback handling.
- Frontend: expand task status model/step display and adjust polling/error handling to avoid premature FAILED transitions.
- Local v2 scripts: add isolated startup/port-stop utilities and a static frontend server for the built
dist.
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
| stop_v2_ports.bat | Utility to stop processes listening on the v2 ports. |
| start_backend_18483.cmd | Convenience script for starting backend with v2-specific env defaults. |
| serve_frontend_13015.py | Static server for serving the built frontend with SPA fallback + no-store caching. |
| run.bat | Orchestrates stopping old ports + starting backend/frontend and readiness checks for isolated v2 ports. |
| BillNote_frontend/src/store/taskStore/index.ts | Updates task status union to match richer backend lifecycle states. |
| BillNote_frontend/src/services/note.ts | Removes duplicated toast error to let callers handle errors. |
| BillNote_frontend/src/pages/HomePage/components/StepBar.tsx | Prevents invalid currentStep from breaking the step index. |
| BillNote_frontend/src/pages/HomePage/components/NoteForm.tsx | Improves model/provider selection handling and error reporting on submit. |
| BillNote_frontend/src/pages/HomePage/components/MarkdownViewer.tsx | Updates step list to include PENDING and SAVING states. |
| BillNote_frontend/src/hooks/useTaskPolling.ts | Avoids flipping tasks to FAILED on transient polling errors. |
| BillNote_frontend/package-lock.json | Adds @ant-design/x and associated dependency graph changes. |
| backend/main.py | Expands CORS handling for localhost origins via regex. |
| backend/app/utils/video_reader.py | Makes frame/grid dirs unique per run, caps frames, and improves sampling + ffmpeg tool lookup. |
| backend/app/transcriber/transcriber_provider.py | Ensures BCUT transcriber is not reused across concurrent note jobs. |
| backend/app/transcriber/bcut.py | Adds retry/backoff for BCUT upload commit step. |
| backend/app/services/task_serial_executor.py | Replaces old executor with bounded-concurrency executor + queue stats. |
| backend/app/services/note.py | Improves cache decoding, adds transcript reuse/fallback logic, and adjusts status updates. |
| backend/app/routers/note.py | Submits tasks to bounded executor, makes result JSON authoritative, adds queue-status endpoint. |
| backend/app/downloaders/bilibili_downloader.py | Large rewrite to add CDP-first fallback, resumable downloads, and cache reuse logic. |
Files not reviewed (1)
- BillNote_frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import os | ||
| import http.server | ||
| import socketserver | ||
| os.chdir(r"C:\codex\bilinote_latest_v2.0.0\BillNote_frontend\dist") |
| if not os.path.exists(self.translate_path(self.path)): | ||
| self.path = "/index.html" | ||
| return super().do_GET() | ||
| with socketserver.TCPServer(("0.0.0.0", 13015), Handler) as httpd: |
Comment on lines
+9
to
+15
| set "BACKEND_HOST=0.0.0.0" | ||
| set "APP_PORT=%FRONTEND_PORT%" | ||
| set "VITE_FRONTEND_PORT=%FRONTEND_PORT%" | ||
| set "VITE_API_BASE_URL=http://127.0.0.1:%BACKEND_PORT%/api" | ||
| set "VITE_SCREENSHOT_BASE_URL=http://127.0.0.1:%BACKEND_PORT%/static/screenshots" | ||
| set "API_BASE_URL=http://127.0.0.1:%BACKEND_PORT%" | ||
| set "SCREENSHOT_BASE_URL=http://127.0.0.1:%BACKEND_PORT%/static/screenshots" |
Comment on lines
+10
to
+16
| set "APP_PORT=%FRONTEND_PORT%" | ||
| set "VITE_FRONTEND_PORT=%FRONTEND_PORT%" | ||
| set "VITE_API_BASE_URL=http://127.0.0.1:%BACKEND_PORT%/api" | ||
| set "VITE_SCREENSHOT_BASE_URL=http://127.0.0.1:%BACKEND_PORT%/static/screenshots" | ||
| set "API_BASE_URL=http://127.0.0.1:%BACKEND_PORT%" | ||
| set "SCREENSHOT_BASE_URL=http://127.0.0.1:%BACKEND_PORT%/static/screenshots" | ||
| set "NOTE_TASK_MAX_WORKERS=2" |
Comment on lines
+33
to
+47
| ( | ||
| echo @echo off | ||
| echo cd /d "%%~dp0backend" | ||
| echo set "BACKEND_PORT=18483" | ||
| echo set "BACKEND_HOST=0.0.0.0" | ||
| echo set "VIDEO_UNDERSTANDING_MAX_FRAMES=8" | ||
| echo set "BILIBILI_CDP_FIRST=1" | ||
| echo set "BILIBILI_LOWEST_VIDEO_FIRST=1" | ||
| echo set "BILIBILI_LOWEST_AUDIO_FIRST=1" | ||
| echo set "BILIBILI_MEDIA_RETRY_ATTEMPTS=8" | ||
| echo set "BILIBILI_SKIP_YTDLP_SUBTITLES=1" | ||
| echo set "NOTE_TASK_MAX_WORKERS=2" | ||
| echo "..\.venv\Scripts\python.exe" main.py | ||
| ) > "%ROOT%start_backend_18483.cmd" | ||
| start "BiliNote v2 Backend 18483" /D "%ROOT%" "%ROOT%start_backend_18483.cmd" |
Comment on lines
+440
to
+453
| def _download_audio_via_cdp(self, video_url: str, output_dir: str) -> AudioDownloadResult: | ||
| logger.info("yt-dlp ? B ?????? Chrome CDP ????") | ||
| state = asyncio.run(self._get_playinfo_from_cdp(video_url)) | ||
| playinfo = state["playinfo"] | ||
| data = playinfo["data"] | ||
| audio_streams = data["dash"]["audio"] | ||
| audio = self._select_dash_stream( | ||
| audio_streams, | ||
| prefer_lowest=self._env_enabled("BILIBILI_LOWEST_AUDIO_FIRST", True), | ||
| ) | ||
|
|
||
| video_id = state.get("bvid") or self._extract_bvid(video_url) | ||
| title = (state.get("title") or video_id).replace("_????_bilibili", "") | ||
| duration = int(state.get("duration") or data.get("duration") or 0) |
Comment on lines
+660
to
+661
| return f"???????: {video_path}" | ||
| return f"???????: {video_path}" |
| "url": "https://opencollective.com/ant-design" | ||
| }, | ||
| "peerDependencies": { | ||
| "antd": "^6.1.1", |
| @echo off | ||
| cd /d "%~dp0backend" | ||
| set "BACKEND_PORT=18483" | ||
| set "BACKEND_HOST=0.0.0.0" |
| @@ -0,0 +1,2 @@ | |||
| @echo off | |||
| powershell -NoProfile -ExecutionPolicy Bypass -Command "foreach($port in @(18483,13015)){ $listeners = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue; foreach($listener in $listeners){ $procId = [int]$listener.OwningProcess; Write-Host ('Stopping PID ' + $procId + ' on port ' + $port); Stop-Process -Id $procId -Force -ErrorAction SilentlyContinue } }" | |||
Owner
|
@copilot resolve the merge conflicts in this pull request |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the local BiliNote v2 stabilization commit prepared by Codex. It fixes bounded concurrent note generation, Bilibili/CDP fallback handling, frontend polling stuck states, and v2 isolated startup scripts. Verification: backend py_compile, frontend npm run build, task_queue_status on 18483, frontend 13015 HTTP 200 no-store, git diff --cached --check.