Skip to content

Stabilize note generation under provider limits#334

Open
hzsw1234 wants to merge 1 commit into
JefferyHcool:masterfrom
hzsw1234:master
Open

Stabilize note generation under provider limits#334
hzsw1234 wants to merge 1 commit into
JefferyHcool:masterfrom
hzsw1234:master

Conversation

@hzsw1234
Copy link
Copy Markdown

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.

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
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread serve_frontend_13015.py
import os
import http.server
import socketserver
os.chdir(r"C:\codex\bilinote_latest_v2.0.0\BillNote_frontend\dist")
Comment thread serve_frontend_13015.py
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 thread run.bat
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 thread run.bat
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 thread run.bat
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",
Comment thread start_backend_18483.cmd
@echo off
cd /d "%~dp0backend"
set "BACKEND_PORT=18483"
set "BACKEND_HOST=0.0.0.0"
Comment thread stop_v2_ports.bat
@@ -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 } }"
@JefferyHcool
Copy link
Copy Markdown
Owner

@copilot resolve the merge conflicts in this pull request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants