bilisum 1.20.0 → 1.20.1-alpha.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bilisum",
3
- "version": "1.20.0",
3
+ "version": "1.20.1-alpha.1",
4
4
  "description": "BiliSum CLI: control the installed BiliSum app, or run standalone with its own runtime.",
5
5
  "bin": {
6
6
  "bilisum": "bin/bilisum.js"
package/runtime/VERSION CHANGED
@@ -1 +1 @@
1
- 1.20.0
1
+ 1.20.1-alpha.1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "video-sum-service"
7
- version = "1.20.0"
7
+ version = "1.20.1-alpha.1"
8
8
  description = "Local backend service for the video summarizer."
9
9
  requires-python = ">=3.12"
10
10
  dependencies = [
@@ -378,23 +378,42 @@ def update_settings(payload: SettingsUpdatePayload, request: Request, background
378
378
  )
379
379
  if payload.runtime_channel is not None:
380
380
  payload = payload.model_copy(update={"runtime_channel": requested_runtime_channel})
381
- ensure_runtime_channel(requested_runtime_channel)
381
+ # Runtime bootstrap/sync is expensive (it can copy the whole managed
382
+ # runtime tree when the channel metadata mismatches) and is only needed
383
+ # when the runtime channel itself changes. Ordinary saves (e.g. toggling
384
+ # the summary prompt router mode) must not re-sync the runtime — doing so
385
+ # blocks the response and can fail with a bare 500 under concurrent saves.
386
+ runtime_channel_changed = requested_runtime_channel != previous_settings.runtime_channel
387
+ if runtime_channel_changed:
388
+ try:
389
+ ensure_runtime_channel(requested_runtime_channel)
390
+ except HTTPException:
391
+ raise
392
+ except Exception as exc:
393
+ logger.warning(
394
+ "settings save: ensure runtime channel failed channel=%s error=%s",
395
+ requested_runtime_channel,
396
+ exc,
397
+ )
398
+ raise HTTPException(status_code=500, detail=f"运行环境切换失败:{exc}") from exc
382
399
 
383
400
  current_settings = settings_manager.save(payload)
384
401
  active_runtime_channel = normalize_runtime_channel(current_settings.runtime_channel, allow_unknown_gpu=True)
385
- bootstrap_managed_runtime(active_runtime_channel)
386
- prepend_runtime_path(active_runtime_channel)
387
- activate_runtime_pythonpath(active_runtime_channel)
388
- current_settings.data_dir.mkdir(parents=True, exist_ok=True)
389
- current_settings.cache_dir.mkdir(parents=True, exist_ok=True)
390
- current_settings.tasks_dir.mkdir(parents=True, exist_ok=True)
391
- runtime_channel_changed = previous_settings.runtime_channel != current_settings.runtime_channel
392
402
  if runtime_channel_changed:
403
+ bootstrap_managed_runtime(active_runtime_channel)
404
+ prepend_runtime_path(active_runtime_channel)
405
+ activate_runtime_pythonpath(active_runtime_channel)
393
406
  clear_environment_probe_cache(previous_settings.runtime_channel)
394
407
  clear_environment_probe_cache(current_settings.runtime_channel)
395
408
  _clear_knowledge_service_cache(request.app.state)
409
+ current_settings.data_dir.mkdir(parents=True, exist_ok=True)
410
+ current_settings.cache_dir.mkdir(parents=True, exist_ok=True)
411
+ current_settings.tasks_dir.mkdir(parents=True, exist_ok=True)
396
412
  # Defer worker rebuild + env probe to background so the save response
397
413
  # returns immediately instead of blocking on subprocess / thread init.
414
+ # build_worker() re-runs bootstrap_managed_runtime / prepend_runtime_path /
415
+ # activate_runtime_pythonpath for the active channel, so the process-level
416
+ # runtime environment stays in sync even for channel-unchanged saves.
398
417
  background_tasks.add_task(
399
418
  _rebuild_worker_after_save,
400
419
  request.app.state,
@@ -45,6 +45,7 @@ from video_sum_infra.runtime import (
45
45
  runtime_library_dirs,
46
46
  runtime_python_candidates,
47
47
  runtime_python_executable,
48
+ runtime_python_stdlib_healthy,
48
49
  runtime_pythonpath_dirs,
49
50
  runtime_site_packages_dir,
50
51
  sanitized_subprocess_dll_search,
@@ -93,6 +94,13 @@ _RUNTIME_ROOT_STALE_FILES: frozenset[str] = frozenset({"pyvenv.cfg"})
93
94
  _RUNTIME_REQUIREMENT_NAME_PATTERN = re.compile(r"^\s*([A-Za-z0-9][A-Za-z0-9_.-]*)")
94
95
  _RUNTIME_CHANNEL_PATTERN = re.compile(r"^(base|gpu-cu\d+)$")
95
96
  _TORCH_FAMILY_PACKAGES: tuple[str, ...] = ("torch", "torchvision", "torchaudio")
97
+ _PIP_REDIRECT_ENV_KEYS: tuple[str, ...] = (
98
+ "PIP_TARGET",
99
+ "PIP_PREFIX",
100
+ "PIP_USER",
101
+ "PYTHONUSERBASE",
102
+ "PIP_CONFIG_FILE",
103
+ )
96
104
 
97
105
 
98
106
  def _knowledge_dependency_probe_fields(package: str) -> tuple[str, str, str]:
@@ -258,7 +266,13 @@ def windows_hidden_subprocess_kwargs() -> dict[str, object]:
258
266
 
259
267
  def runtime_subprocess_env(runtime_channel: str) -> dict[str, str]:
260
268
  env = dict(os.environ)
261
- for key in ("PYTHONHOME", "PYTHONPATH", "PYTHONEXECUTABLE", "__PYVENV_LAUNCHER__"):
269
+ for key in (
270
+ "PYTHONHOME",
271
+ "PYTHONPATH",
272
+ "PYTHONEXECUTABLE",
273
+ "__PYVENV_LAUNCHER__",
274
+ *_PIP_REDIRECT_ENV_KEYS,
275
+ ):
262
276
  env.pop(key, None)
263
277
  temp_dir = settings_manager.current.cache_dir / "runtime-temp" / runtime_channel
264
278
  try:
@@ -338,7 +352,13 @@ def run_command(command: list[str], runtime_channel: str, timeout: int = 3600) -
338
352
 
339
353
  def run_host_command(command: list[str], timeout: int = 3600) -> subprocess.CompletedProcess[str]:
340
354
  env = dict(os.environ)
341
- for key in ("PYTHONHOME", "PYTHONPATH", "PYTHONEXECUTABLE", "__PYVENV_LAUNCHER__"):
355
+ for key in (
356
+ "PYTHONHOME",
357
+ "PYTHONPATH",
358
+ "PYTHONEXECUTABLE",
359
+ "__PYVENV_LAUNCHER__",
360
+ *_PIP_REDIRECT_ENV_KEYS,
361
+ ):
342
362
  env.pop(key, None)
343
363
  env["PYTHONIOENCODING"] = "utf-8"
344
364
  env["PYTHONUTF8"] = "1"
@@ -951,6 +971,7 @@ def pip_install_with_fallbacks(
951
971
  str(python_executable),
952
972
  "-m",
953
973
  "pip",
974
+ "--isolated",
954
975
  "install",
955
976
  "--disable-pip-version-check",
956
977
  "--upgrade",
@@ -1000,6 +1021,53 @@ def pip_install_with_fallbacks(
1000
1021
  raise HTTPException(status_code=500, detail=pip_install_error_detail(package_label, attempts))
1001
1022
 
1002
1023
 
1024
+ def _ensure_runtime_install_target(runtime_channel: str) -> Path:
1025
+ """Return a writable, managed target for packages installed into a frozen runtime.
1026
+
1027
+ Relocatable Python distributions can retain the build-time ``sys.prefix`` or
1028
+ ``purelib`` path (for example ``/install`` on macOS). Allowing pip to use
1029
+ that implicit path makes an otherwise healthy dependency download fail with
1030
+ ``OSError: [Errno 30] Read-only file system``. Keep installation scoped to
1031
+ the user-writable managed runtime and fail before pip starts if it cannot be
1032
+ written, so the UI reports the real repair path.
1033
+ """
1034
+ target = _assert_path_within_managed_runtime_root(
1035
+ runtime_site_packages_dir(runtime_channel), field_name="runtime install target"
1036
+ )
1037
+ try:
1038
+ target.mkdir(parents=True, exist_ok=True)
1039
+ with tempfile.NamedTemporaryFile(
1040
+ mode="w",
1041
+ encoding="utf-8",
1042
+ prefix=".bilisum-install-write-test-",
1043
+ dir=target,
1044
+ delete=True,
1045
+ ) as probe:
1046
+ probe.write("ok")
1047
+ probe.flush()
1048
+ except OSError as exc:
1049
+ logger.error(
1050
+ "runtime dependency install target is not writable runtime_channel=%s target=%s error=%s",
1051
+ _sanitize_for_log(runtime_channel),
1052
+ _sanitize_for_log(str(target)),
1053
+ _sanitize_for_log(str(exc)),
1054
+ )
1055
+ raise HTTPException(
1056
+ status_code=500,
1057
+ detail=(
1058
+ f"知识库依赖安装目录不可写:{target}。"
1059
+ "请检查应用数据目录权限,或同步/重建当前运行环境后重试。"
1060
+ f" 原因:{exc}"
1061
+ ),
1062
+ ) from exc
1063
+ logger.info(
1064
+ "runtime dependency install target prepared runtime_channel=%s target=%s",
1065
+ _sanitize_for_log(runtime_channel),
1066
+ _sanitize_for_log(str(target)),
1067
+ )
1068
+ return target
1069
+
1070
+
1003
1071
  def _run_pip_install(
1004
1072
  python_executable: Path,
1005
1073
  runtime_channel: str,
@@ -1248,7 +1316,14 @@ def ensure_runtime_channel(runtime_channel: str) -> Path | None:
1248
1316
 
1249
1317
  base_metadata = read_runtime_metadata(base_dir)
1250
1318
  target_metadata = read_runtime_metadata(target_dir)
1251
- target_ready = runtime_python_executable(runtime_channel) is not None
1319
+ # "Ready" means more than python.exe existing: a portable runtime whose
1320
+ # DLLs went missing (interrupted refresh) still passes the metadata check
1321
+ # but fails every subprocess with "No module named '_socket'". Treat it
1322
+ # as not ready so the runtime gets re-synced from base / the seed below.
1323
+ target_ready = (
1324
+ runtime_python_executable(runtime_channel) is not None
1325
+ and runtime_python_stdlib_healthy(target_dir)
1326
+ )
1252
1327
  target_matches_base = runtime_metadata_matches_base(target_metadata, base_metadata)
1253
1328
  if target_ready and target_matches_base:
1254
1329
  _ensure_runtime_sitecustomize(runtime_channel)
@@ -1400,7 +1475,10 @@ def inspect_runtime_channels() -> dict[str, object]:
1400
1475
  metadata = read_runtime_metadata(runtime_dir)
1401
1476
  python_executable = runtime_python_executable(runtime_channel)
1402
1477
  exists = runtime_dir.exists()
1403
- ready = python_executable is not None
1478
+ ready = (
1479
+ python_executable is not None
1480
+ and runtime_python_stdlib_healthy(runtime_dir)
1481
+ )
1404
1482
  app_version = str(metadata.get("appVersion") or "")
1405
1483
  layout = str(metadata.get("runtimeLayout") or "")
1406
1484
  cached_environment = (
@@ -2332,7 +2410,13 @@ def install_local_asr(reinstall: bool, repository: SqliteTaskRepository, *, sess
2332
2410
  start_install_session(session_id, "本地 ASR")
2333
2411
  if use_streaming and use_current_python:
2334
2412
  host_env = dict(os.environ)
2335
- for key in ("PYTHONHOME", "PYTHONPATH", "PYTHONEXECUTABLE", "__PYVENV_LAUNCHER__"):
2413
+ for key in (
2414
+ "PYTHONHOME",
2415
+ "PYTHONPATH",
2416
+ "PYTHONEXECUTABLE",
2417
+ "__PYVENV_LAUNCHER__",
2418
+ *_PIP_REDIRECT_ENV_KEYS,
2419
+ ):
2336
2420
  host_env.pop(key, None)
2337
2421
  host_env["PYTHONIOENCODING"] = "utf-8"
2338
2422
  host_env["PYTHONUTF8"] = "1"
@@ -2454,7 +2538,13 @@ def install_funasr(reinstall: bool, repository: SqliteTaskRepository, *, session
2454
2538
  start_install_session(session_id, "FunASR")
2455
2539
  if use_streaming and use_current_python:
2456
2540
  host_env = dict(os.environ)
2457
- for key in ("PYTHONHOME", "PYTHONPATH", "PYTHONEXECUTABLE", "__PYVENV_LAUNCHER__"):
2541
+ for key in (
2542
+ "PYTHONHOME",
2543
+ "PYTHONPATH",
2544
+ "PYTHONEXECUTABLE",
2545
+ "__PYVENV_LAUNCHER__",
2546
+ *_PIP_REDIRECT_ENV_KEYS,
2547
+ ):
2458
2548
  host_env.pop(key, None)
2459
2549
  host_env["PYTHONIOENCODING"] = "utf-8"
2460
2550
  host_env["PYTHONUTF8"] = "1"
@@ -2614,12 +2704,26 @@ def install_knowledge_dependencies(
2614
2704
  if runtime_dir is None or python_executable is None:
2615
2705
  raise HTTPException(status_code=500, detail="Managed runtime is unavailable.")
2616
2706
 
2707
+ # Never let a frozen/portable interpreter select its build-time pip target
2708
+ # (commonly /install on macOS). The service imports dependencies from this
2709
+ # exact directory, so the first install must use it instead of waiting for
2710
+ # a post-install fallback that is never reached when pip hits errno 30.
2711
+ install_target = None if use_current_python else _ensure_runtime_install_target(runtime_channel)
2712
+
2617
2713
  use_streaming = session_id is not None
2618
2714
  if use_streaming:
2619
2715
  start_install_session(session_id, "知识库依赖")
2716
+ if install_target is not None:
2717
+ append_install_log(session_id, f"[知识库] pip 安装目标:{install_target}\n")
2620
2718
  if use_streaming and use_current_python:
2621
2719
  host_env = dict(os.environ)
2622
- for key in ("PYTHONHOME", "PYTHONPATH", "PYTHONEXECUTABLE", "__PYVENV_LAUNCHER__"):
2720
+ for key in (
2721
+ "PYTHONHOME",
2722
+ "PYTHONPATH",
2723
+ "PYTHONEXECUTABLE",
2724
+ "__PYVENV_LAUNCHER__",
2725
+ *_PIP_REDIRECT_ENV_KEYS,
2726
+ ):
2623
2727
  host_env.pop(key, None)
2624
2728
  host_env["PYTHONIOENCODING"] = "utf-8"
2625
2729
  host_env["PYTHONUTF8"] = "1"
@@ -2747,6 +2851,7 @@ def install_knowledge_dependencies(
2747
2851
  reinstall=reinstall or repair_reinstall,
2748
2852
  timeout=1800,
2749
2853
  runner=pip_runner,
2854
+ install_target=install_target,
2750
2855
  )
2751
2856
  except subprocess.CalledProcessError as exc:
2752
2857
  if isinstance(pip_runner, _StreamingRunner):
@@ -2794,7 +2899,7 @@ def install_knowledge_dependencies(
2794
2899
  reinstall=False,
2795
2900
  timeout=1800,
2796
2901
  runner=pip_runner,
2797
- install_target=runtime_site_packages_dir(runtime_channel),
2902
+ install_target=install_target,
2798
2903
  )
2799
2904
  except subprocess.CalledProcessError as exc:
2800
2905
  if isinstance(pip_runner, _StreamingRunner):
@@ -1,6 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import json
4
+ import os
5
+ import threading
4
6
  from pathlib import Path
5
7
  from typing import Literal
6
8
 
@@ -151,6 +153,10 @@ class SettingsManager:
151
153
  self._base_settings = base_settings
152
154
  self._settings = base_settings
153
155
  self._settings_path = Path(base_settings.data_dir) / "settings.json"
156
+ # Serialize saves: concurrent PUT /settings requests (e.g. a quick
157
+ # double-click on the summary prompt mode toggle) must not race on
158
+ # the shared settings file.
159
+ self._save_lock = threading.Lock()
154
160
 
155
161
  @property
156
162
  def current(self) -> ServiceSettings:
@@ -212,16 +218,25 @@ class SettingsManager:
212
218
  return self._settings
213
219
 
214
220
  def save(self, payload: SettingsUpdatePayload) -> ServiceSettings:
215
- current_dump = self._settings.model_dump(mode="json")
216
- updates = payload.model_dump(exclude_none=True, exclude={"llm_test_scope"})
217
- for field in SECRET_SETTINGS_FIELDS:
218
- if field in updates and is_blank_or_masked_secret(updates[field]) and current_dump.get(field):
219
- updates.pop(field)
220
- next_settings = ServiceSettings.model_validate({**current_dump, **updates})
221
- self._settings_path.parent.mkdir(parents=True, exist_ok=True)
222
- self._settings_path.write_text(
223
- json.dumps(next_settings.model_dump(mode="json"), ensure_ascii=False, indent=2),
224
- encoding="utf-8",
225
- )
226
- self._settings = next_settings
227
- return self._settings
221
+ with self._save_lock:
222
+ current_dump = self._settings.model_dump(mode="json")
223
+ updates = payload.model_dump(exclude_none=True, exclude={"llm_test_scope"})
224
+ for field in SECRET_SETTINGS_FIELDS:
225
+ if (
226
+ field in updates
227
+ and is_blank_or_masked_secret(updates[field])
228
+ and current_dump.get(field)
229
+ ):
230
+ updates.pop(field)
231
+ next_settings = ServiceSettings.model_validate({**current_dump, **updates})
232
+ self._settings_path.parent.mkdir(parents=True, exist_ok=True)
233
+ # Write atomically (temp file + rename) so an interrupted or
234
+ # concurrent write can never leave a truncated settings.json.
235
+ tmp_path = self._settings_path.with_name(self._settings_path.name + ".tmp")
236
+ tmp_path.write_text(
237
+ json.dumps(next_settings.model_dump(mode="json"), ensure_ascii=False, indent=2),
238
+ encoding="utf-8",
239
+ )
240
+ os.replace(tmp_path, self._settings_path)
241
+ self._settings = next_settings
242
+ return self._settings
@@ -339,7 +339,7 @@ Minimum version required to store current data is: `+c+`.
339
339
  `,(0,R.jsx)(`strong`,{children:`User Template:`}),`
340
340
  `,e.user_prompt_template]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Vn(e.id),children:`收起`})]})]},e.id)}let[nr,cr]=(0,S.useState)(new Set),lr=nr.size>0;function dr(){Object.values(nn.current).forEach(e=>{e&&(e.open=!1)}),cr(new Set),Dn(!1),Gn()}function fr(){let e=tn.current;e?.scrollIntoView({behavior:`smooth`,block:`start`}),e?.scrollTo({top:0,behavior:`smooth`}),e?.closest(`.settings-content`)?.scrollTo({top:0,behavior:`smooth`}),document.querySelector(`.app-main`)?.scrollTo({top:0,behavior:`smooth`}),document.querySelector(`.app-content`)?.scrollTo({top:0,behavior:`smooth`}),document.scrollingElement?.scrollTo({top:0,behavior:`smooth`}),window.scrollTo({top:0,behavior:`smooth`})}function pr(e,t){let n=t.target.open;cr(t=>{let r=new Set(t);return n?r.add(e):r.delete(e),r})}function I(){Dn(e=>{let t=!e;return cr(e=>{let n=new Set(e);return t?n.add(`presets`):n.delete(`presets`),n}),t})}(0,S.useLayoutEffect)(()=>{let e=en.current;if(!e)return;let t=()=>{let t=Math.min(24,window.innerHeight-e.offsetHeight-24);e.style.setProperty(`--settings-nav-sticky-top`,`${Math.round(t)}px`)};t();let n=new ResizeObserver(t);return n.observe(e),window.addEventListener(`resize`,t),()=>{n.disconnect(),window.removeEventListener(`resize`,t)}},[]),(0,S.useEffect)(()=>{v||h(nJ(e.settings))},[v,e.settings]),(0,S.useEffect)(()=>{_(e.environment)},[e.environment]),(0,S.useEffect)(()=>{dt(e.systemInfo?.service?.log_file||t.logPath||``)},[t.logPath,e.systemInfo?.service?.log_file]),(0,S.useEffect)(()=>{mr(),gr({silent:!0})},[]),(0,S.useEffect)(()=>{let e=window.setInterval(()=>{gr({silent:!0})},1800*1e3);return()=>window.clearInterval(e)},[]),(0,S.useEffect)(()=>{Pt===`prompts`&&Ln()},[Pt]),(0,S.useEffect)(()=>{if(!Oe)return;let e=!1,t=window.setInterval(()=>{(async()=>{try{let t=await L.pollBilibiliCookieQrcode(Oe);if(e)return;if(t.status===`pending`){De(`等待手机 B 站扫码。`);return}if(t.status===`scanned`){De(`已扫码,请在手机 B 站上确认登录。`);return}if(t.status===`expired`){De(t.message||`二维码已过期,请重新获取。`),ke(``),je(``);return}if(t.status===`confirmed`&&t.cookiesFile){let n=await L.updateSettings({ytdlp_cookies_file:t.cookiesFile,ytdlp_cookies_browser:``});if(e)return;h(nJ(n.settings)),y(!1),w(n.message||`设置已保存`),De(`B 站登录态已保存,捕获 ${t.cookieCount||0} 条 cookies。`),ke(``),je(``),a(n.settings,g)}}catch(t){e||De(t instanceof Error?t.message:`二维码登录状态检查失败。`)}})()},2e3);return()=>{e=!0,window.clearInterval(t)}},[Oe,g,a]);async function mr(){try{let n=await L.getSystemLogs();lt(n.content||`日志文件存在,但当前还没有内容。`),dt(n.path||e.systemInfo?.service?.log_file||t.logPath||``)}catch(n){try{let n=await window.desktop?.logs.readServiceLogTail(200);if(n){lt(n.content||`本地日志文件存在,但当前还没有内容。`),dt(n.path||e.systemInfo?.service?.log_file||t.logPath||``),pt(`服务接口不可用,已切换为本地日志读取。`);return}}catch{}lt(n instanceof Error?n.message:`读取日志失败`)}}(0,S.useEffect)(()=>{if(!se)return;let e=setInterval(()=>{mr()},5e3);return()=>clearInterval(e)},[se]),(0,S.useEffect)(()=>{let e=de.current;e&&(e.scrollTop=e.scrollHeight)},[ct]);let hr=le===`all`?ct:ct.split(`
341
341
  `).filter(e=>e.includes(le)).join(`
342
- `);(0,S.useEffect)(()=>{let e=de.current;e&&requestAnimationFrame(()=>{e.scrollTop=e.scrollHeight})},[hr]);async function gr(e={}){try{at(!0),e.silent||rt(`正在检查所有运行环境...`);let t=await L.getRuntimeStatus();if(tt(t),m?.runtime_channel){let e=await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});_(e),a(m,e)}let n=t.channels.filter(e=>e.needsUpdate).length;e.silent||rt(n>0?`${n} 个运行环境需要同步基础版本。`:`所有已安装运行环境均为最新基础版本。`)}catch(t){e.silent||rt(t instanceof Error?t.message:`运行环境检查失败`)}finally{at(!1)}}async function _r(){if(!(!m||ot))try{st(!0),rt(`正在同步需要更新的运行环境...`);let e=await L.syncRuntime();e.runtimeStatus?tt(e.runtimeStatus):await gr({silent:!0});let t=e.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});_(t),a(m,t);let n=e.channels?.filter(e=>e.synced).length??0;rt(n>0?`已同步 ${n} 个运行环境,保留 CUDA / ASR / 知识库扩展包。`:`运行环境已检查,无需同步。`),i()}catch(e){rt(e instanceof Error?e.message:`运行环境同步失败`)}finally{st(!1)}}let vr=(0,S.useCallback)(async()=>{if(!m||!window.desktop?.fileManager){Nt(`当前环境不支持文件管理。`);return}try{kt(!0),Nt(``);let t;if(e.serviceOnline)try{t=(await L.listTasks()).map(e=>e.task_id)}catch{t=void 0}Dt(await window.desktop.fileManager.getStorageOverview({taskIds:t})),t||Nt(`服务离线:已展示本地占用情况,清理操作需要在服务在线时确认引用关系。`)}catch(e){Nt(e instanceof Error?e.message:`读取文件占用失败`)}finally{kt(!1)}},[m,e.serviceOnline]);async function yr(e){!m||!window.desktop?.fileManager||await window.desktop.fileManager.openDirectory(e)}async function br(){if(!(!m||!window.desktop?.fileManager||!wr))try{jt(!0),Nt(``);let e=(await L.listTasks()).map(e=>e.task_id),t=await window.desktop.fileManager.getStorageOverview({taskIds:e}),n=t.cleanup.orphanTaskCount+t.cleanup.cacheCandidateCount,r=t.cleanup.orphanTaskBytes+t.cleanup.cacheCandidateBytes;if(n<=0){Dt(t),Nt(`当前没有可安全清理的缓存或孤儿文件。`);return}if(!window.confirm(`将删除 ${n} 项可回收内容,预计释放 ${aJ(r)}。\n\n包含:${t.cleanup.orphanTaskCount} 个孤儿任务目录、${t.cleanup.cacheCandidateCount} 个缓存项。\n此操作不会删除仍被引用的任务结果。`)){Dt(t),Nt(`已取消清理。`);return}let i=await window.desktop.fileManager.cleanupOrphans({taskIds:e});await vr(),Nt(`已清理 ${i.deletedCount} 项内容,释放约 ${aJ(i.reclaimedBytes)}。`)}catch(e){Nt(e instanceof Error?e.message:`清理文件失败`)}finally{jt(!1)}}async function xr(){try{Yt(!0),Zt(``),$t((await L.listTasks()).slice(0,Xq))}catch(e){Zt(e instanceof Error?e.message:`读取任务列表失败`)}finally{Yt(!1)}}let Sr=!!t.backend?.running,Cr=!!t.backend?.ready,wr=e.serviceOnline,Tr=ut||e.systemInfo?.service?.log_file||t.logPath||`-`,Er=`gpu-${m?.cuda_variant||`cu128`}`,Dr=Gq.find(e=>e.id===Pt)||Gq[0],Or=Gq.filter(e=>e.group===`workflow`),kr=Gq.filter(e=>e.group===`system`),Ar=Wt.trim().toLowerCase(),jr=Ar.split(/\s+/).filter(Boolean),Mr=Ar?iJ.map(e=>{let t=Gq.find(t=>t.id===e.category),n=[e.title,e.description,t?.label||``,t?.description||``,...e.keywords].join(` `).toLowerCase();return jr.every(e=>n.includes(e))?{...e,categoryLabel:t?.label||e.category}:null}).filter(e=>!!e).slice(0,8):[],Pr=tJ(m?.llm_api_key,m?.llm_api_key_configured),Fr=tJ(m?.visual_evidence_api_key,m?.visual_evidence_api_key_configured)||Pr,Ir=tJ(m?.knowledge_llm_api_key,m?.knowledge_llm_api_key_configured),Lr=tJ(m?.siliconflow_embedding_api_key,m?.siliconflow_embedding_api_key_configured),Rr=String(m?.knowledge_embedding_provider||`local_huggingface`).trim().toLowerCase()===`siliconflow`,zr=!!m?.llm_enabled,Br=!!m?.visual_multimodal_enabled,Vr=!!(m?.llm_enabled&&Pr&&String(m?.llm_base_url||``).trim()&&String(m?.llm_model||``).trim()),Hr=!!(m?.visual_multimodal_enabled&&Fr&&String(m?.visual_evidence_base_url||m?.llm_base_url||``).trim()&&String(m?.visual_evidence_model||m?.llm_model||``).trim()),Wr=wt.main,Gr=wt.visual,Kr=Wr.status===`available`?`可用`:Wr.status===`unavailable`?`不可用`:Wr.status===`checking`?`检查中`:Vr?`可用`:zr?`待配置`:`关闭`,Jr=Wr.status===`available`||Wr.status===`unknown`&&Vr?`success`:Wr.status===`unavailable`?`danger`:Wr.status===`checking`||zr?`warning`:``,Yr=zr?Wr.status===`unavailable`?`不可用`:Vr?`已配置`:`待补全`:`未启用`,Xr=Gr.status===`available`?`可用`:Gr.status===`unavailable`?`不可用`:Gr.status===`checking`?`检查中`:Hr?`可用`:Br?`待确认`:`关闭`,Zr=Gr.status===`available`||Gr.status===`unknown`&&Hr?`success`:Gr.status===`unavailable`?`danger`:Gr.status===`checking`||Br?`warning`:``,Qr=Br?Gr.status===`unavailable`?`不可用`:Hr?`已配置`:`跟随或待补全`:`未启用`,$r=(()=>{let e=m?.visual_note_mode||`text`;return e===`vlm_integrated`?`multimodal`:e===`frame_insert`?`visual`:`text`})(),ei=String(m?.knowledge_llm_mode||`same_as_main`).trim().toLowerCase()===`custom`,ti=ei?!!(m?.knowledge_llm_enabled&&Ir&&String(m?.knowledge_llm_base_url||``).trim()&&String(m?.knowledge_llm_model||``).trim()):!!(m?.llm_enabled&&Pr&&String(m?.llm_base_url||``).trim()&&String(m?.llm_model||``).trim()),ni=!!m?.auto_generate_mindmap,ri=t.version||e.systemInfo?.application?.version||`-`,ii=m?.transcription_provider===`local`?!!g?.localAsrAvailable:m?.transcription_provider===`funasr`?!!g?.funasrAvailable:m?.transcription_provider===`multimodal`?!!(m?.multimodal_asr_api_key_configured&&String(m?.multimodal_asr_base_url||``).trim()&&String(m?.multimodal_asr_model||``).trim()):!!m?.siliconflow_asr_api_key_configured,ai=rr(o),oi=ir(o),si=ar(o),ci=or(o,ri),li=o.status===`checking`||o.status===`downloading`||o.status===`installing`;(0,S.useEffect)(()=>{if(!m||Pt!==`files`)return;let e=window.setTimeout(()=>{vr()},100);return()=>window.clearTimeout(e)},[Pt,vr]),(0,S.useEffect)(()=>{if(!n||!m||an.current===n.nonce)return;an.current=n.nonce;let e=ha(n.issueKey);e&&(Ft(e.category),Lt(e.targetKey))},[n,m]),(0,S.useEffect)(()=>{!r||!m||on.current!==r.nonce&&(on.current=r.nonce,Hn(r.presetId))},[r,m,cn]),(0,S.useEffect)(()=>{if(!It)return;let e=rn.current[It];if(!e)return;let t=window.setTimeout(()=>{e.scrollIntoView({behavior:`smooth`,block:`center`});let t=e.matches(`input, select, textarea, button`)?e:e.querySelector(`input, select, textarea, button`);t instanceof HTMLElement&&t.focus({preventScroll:!0}),zt(It),Lt(null)},80);return()=>window.clearTimeout(t)},[Pt,It]),(0,S.useEffect)(()=>{if(!Rt)return;let e=window.setTimeout(()=>zt(e=>e===Rt?null:e),2200);return()=>window.clearTimeout(e)},[Rt]),(0,S.useEffect)(()=>{Kt&&xr()},[Kt]);let ui=!!g?.funasrInstalled;if((0,S.useEffect)(()=>{!ui&&m?.transcription_provider===`funasr`&&h({...m,transcription_provider:`siliconflow`})},[ui]),(0,S.useEffect)(()=>{L.getEmbeddingPresets().then(e=>Ze(e.presets||{})).catch(()=>{})},[]),!m)return(0,R.jsx)(`section`,{className:`grid-card empty-state-card`,children:`正在加载设置...`});let di=m.transcription_provider===`siliconflow`,fi=m.transcription_provider===`multimodal`,pi=m.transcription_provider===`funasr`,mi=m.transcription_provider===`local`?1:2,hi=mi===1?`当前建议:本地 ASR / CPU 场景任务并发数设为 1,导图并发数设为 1。`:`当前建议:云 ASR 或 GPU 场景任务并发数设为 2,导图并发数设为 1。`,gi=Qt.filter(e=>e.status===`queued`).length,_i=Qt.filter(e=>e.status===`running`).length,vi=!!g?.localAsrInstalled,yi=!!g?.knowledgeDependenciesReady,bi=String(m?.siliconflow_embedding_base_url||Qq).trim(),xi=String(m?.siliconflow_embedding_model||$q).trim(),Si=Rr?!!(Lr&&bi&&xi):yi,Ci=!!(g?.chromadbBroken||g?.sentenceTransformersBroken||g?.modelscopeBroken),wi=Re?.required?.length?Re.required:Rr?[`chromadb`]:[`chromadb`,`sentence-transformers`],Ti=wi.join(` / `),Ei=wi.filter(e=>e===`chromadb`?!g?.chromadbInstalled&&!g?.chromadbBroken:e===`sentence-transformers`?!g?.sentenceTransformersInstalled&&!g?.sentenceTransformersBroken:e===`modelscope`?!g?.modelscopeInstalled&&!g?.modelscopeBroken:!1),Di=yi?`已安装`:Ci?`部分损坏`:`未安装`,Oi=yi?`installed`:Ci?`error`:`missing`,ki=yi?Rr?`chromadb 索引存储已就绪`:`向量库和本地模型依赖已就绪`:Ci?`检测到包导入异常`:`安装 ${Ti}`,Ai=et?.channels.filter(e=>e.needsUpdate)||[];et?.channels.find(e=>e.runtimeChannel===(g?.runtimeChannel||m.runtime_channel));let ji=et?.pipIndexes.map(e=>e.label).join(` / `)||`official / tsinghua / aliyun`,Mi=new Map((Et?.directories||[]).map(e=>[e.key,e])),Ni=Mi.get(`cache`)||null,Pi=Mi.get(`tasks`)||null,z=Mi.get(`logs`)||null,Fi=Mi.get(`runtime`)||null,Ii=!!(wr&&Et?.cleanup.serviceAvailable),Li=(Et?.cleanup.orphanTaskBytes||0)+(Et?.cleanup.cacheCandidateBytes||0),Ri=(Et?.cleanup.orphanTaskCount||0)+(Et?.cleanup.cacheCandidateCount||0);function zi(e){let t=ha(e);t&&(Ft(t.category),Lt(t.targetKey))}function B(e){y(!0),h(e),Tt({main:{status:`unknown`,message:``},visual:{status:`unknown`,message:``}})}function Bi(e){if(Object.keys(e).length===0){kn(null);return}kn(t=>({...t||{},...e}))}function Vi(){!m||!On||(B({...m,...On}),kn(null))}function Hi(e){if(!m)return;let t=m.defaults?.summary_system_prompt||``,n=m.defaults?.summary_user_prompt_template||``,r=e===`system`&&t||m.summary_system_prompt,i=e===`template`&&n||m.summary_user_prompt_template,a={};e===`system`&&m.summary_system_prompt!==r&&(a.summary_system_prompt=m.summary_system_prompt||``),e===`template`&&m.summary_user_prompt_template!==i&&(a.summary_user_prompt_template=m.summary_user_prompt_template||``),Bi(a),B({...m,summary_system_prompt:r,summary_user_prompt_template:i})}function Ui(e){if(!m)return;let t=m.defaults?.knowledge_note_system_prompt||m.knowledge_note_system_prompt,n=m.defaults?.knowledge_note_user_prompt_template||m.knowledge_note_user_prompt_template,r=e===`system`?t:m.knowledge_note_system_prompt,i=e===`template`?n:m.knowledge_note_user_prompt_template,a={};e===`system`&&m.knowledge_note_system_prompt!==r&&(a.knowledge_note_system_prompt=m.knowledge_note_system_prompt||``),e===`template`&&m.knowledge_note_user_prompt_template!==i&&(a.knowledge_note_user_prompt_template=m.knowledge_note_user_prompt_template||``),Bi(a),B({...m,knowledge_note_system_prompt:r,knowledge_note_user_prompt_template:i})}function Wi(e){if(!m)return;let t=m.defaults?.visual_note_system_prompt||m.visual_note_system_prompt,n=m.defaults?.visual_note_user_prompt_template||m.visual_note_user_prompt_template,r=m.defaults?.visual_frame_planning_prompt||m.visual_frame_planning_prompt,i=m.defaults?.visual_vlm_prompt||m.visual_vlm_prompt,a=e===`system`?t:m.visual_note_system_prompt,o=e===`template`?n:m.visual_note_user_prompt_template,s=e===`planning`?r:m.visual_frame_planning_prompt,c=e===`vlm`?i:m.visual_vlm_prompt,l={};e===`system`&&m.visual_note_system_prompt!==a&&(l.visual_note_system_prompt=m.visual_note_system_prompt||``),e===`template`&&m.visual_note_user_prompt_template!==o&&(l.visual_note_user_prompt_template=m.visual_note_user_prompt_template||``),e===`planning`&&m.visual_frame_planning_prompt!==s&&(l.visual_frame_planning_prompt=m.visual_frame_planning_prompt||``),e===`vlm`&&m.visual_vlm_prompt!==c&&(l.visual_vlm_prompt=m.visual_vlm_prompt||``),Bi(l),B({...m,visual_note_system_prompt:a,visual_note_user_prompt_template:o,visual_frame_planning_prompt:s,visual_vlm_prompt:c})}function Gi(e){if(m){if(e===`text`){B({...m,visual_note_mode:`text`,visual_evidence_enabled:!1,visual_evidence_use_llm:!1,visual_multimodal_enabled:!1});return}if(e===`visual`){B({...m,visual_note_mode:`frame_insert`,visual_evidence_enabled:!0,visual_evidence_use_llm:!1,visual_multimodal_enabled:!1});return}B({...m,visual_note_mode:`vlm_integrated`,visual_evidence_enabled:!0,visual_evidence_use_llm:!0,visual_multimodal_enabled:!0})}}function Ki(e){return String(e.host||``).trim()?e.transcription_provider===`siliconflow`&&!String(e.siliconflow_asr_base_url||``).trim()?{message:`请先填写 SiliconFlow Base URL。`,category:`transcription`,targetKey:`siliconflow_asr_base_url`}:e.llm_enabled&&!String(e.llm_base_url||``).trim()?{message:`请先填写 LLM API Base URL。`,category:`generation`,targetKey:`llm_base_url`}:Ji(e)||null:{message:`请先填写监听地址。`,category:`logs`,targetKey:`host`}}function qi(e,t){return t.every(t=>e.includes(t))}function Ji(e){let t=String(e.summary_user_prompt_template||``);if(!qi(t,[`{title}`,`{transcript}`,`{segments_json}`]))return{message:`摘要 User Template 需要保留 {title}、{transcript}、{segments_json} 变量,否则任务无法稳定生成摘要。`,category:`prompts`,targetKey:`summary_user_prompt_template`};for(let e of[`title`,`overview`,`bulletPoints`,`chapters`,`chapterGroups`])if(!t.includes(e))return{message:`摘要 User Template 需要保留 ${e} 输出字段约束。`,category:`prompts`,targetKey:`summary_user_prompt_template`};let n=String(e.knowledge_note_user_prompt_template||``);return qi(n,[`{title}`,`{summary_json}`])?n.includes(`knowledgeNoteMarkdown`)?qi(String(e.visual_frame_planning_prompt||``),[`{title}`,`{summary_json}`])?qi(String(e.visual_vlm_prompt||``),[`{title}`,`{timestamp}`])?qi(String(e.visual_note_user_prompt_template||``),[`{title}`,`{knowledge_note_markdown}`,`{visual_observations_json}`])?null:{message:`图文笔记 User Template 需要保留 {title}、{knowledge_note_markdown}、{visual_observations_json} 变量。`,category:`prompts`,targetKey:`visual_note_user_prompt_template`}:{message:`画面理解 Prompt 至少需要保留 {title} 与 {timestamp} 变量。`,category:`prompts`,targetKey:`visual_vlm_prompt`}:{message:`捕获帧规划 Prompt 至少需要保留 {title} 与 {summary_json} 变量。`,category:`prompts`,targetKey:`visual_frame_planning_prompt`}:{message:`知识笔记 User Template 需要保留 knowledgeNoteMarkdown 输出字段,否则任务会解析失败。`,category:`prompts`,targetKey:`knowledge_note_user_prompt_template`}:{message:`知识笔记 User Template 至少需要保留 {title} 与 {summary_json} 变量。`,category:`prompts`,targetKey:`knowledge_note_user_prompt_template`}}function Yi(e){let t={...e,device_preference:Xn(e.device_preference)};return String(t.knowledge_embedding_provider||``).trim().toLowerCase()===`siliconflow`&&(t.siliconflow_embedding_base_url=String(t.siliconflow_embedding_base_url||Qq).trim(),t.siliconflow_embedding_model=String(t.siliconflow_embedding_model||$q).trim()),e.siliconflow_asr_api_key_configured&&(!String(e.siliconflow_asr_api_key||``).trim()||eJ(e.siliconflow_asr_api_key))&&delete t.siliconflow_asr_api_key,e.multimodal_asr_api_key_configured&&(!String(e.multimodal_asr_api_key||``).trim()||eJ(e.multimodal_asr_api_key))&&delete t.multimodal_asr_api_key,e.llm_api_key_configured&&(!String(e.llm_api_key||``).trim()||eJ(e.llm_api_key))&&delete t.llm_api_key,e.knowledge_llm_api_key_configured&&(!String(e.knowledge_llm_api_key||``).trim()||eJ(e.knowledge_llm_api_key))&&delete t.knowledge_llm_api_key,e.siliconflow_embedding_api_key_configured&&(!String(e.siliconflow_embedding_api_key||``).trim()||eJ(e.siliconflow_embedding_api_key))&&delete t.siliconflow_embedding_api_key,e.visual_evidence_api_key_configured&&(!String(e.visual_evidence_api_key||``).trim()||eJ(e.visual_evidence_api_key))&&delete t.visual_evidence_api_key,e.twelvelabs_api_key_configured&&(!String(e.twelvelabs_api_key||``).trim()||eJ(e.twelvelabs_api_key))&&delete t.twelvelabs_api_key,e.siliconflow_embedding_api_key_configured&&(!String(e.siliconflow_embedding_api_key||``).trim()||eJ(e.siliconflow_embedding_api_key))&&delete t.siliconflow_embedding_api_key,t}async function Xi(e){if(e.preventDefault(),!m||b)return;if(!v){w(``);return}let t=Ki(m);if(t){w(t.message),Ft(t.category),Lt(t.targetKey);return}try{x(!0);let e=await L.updateSettings(Yi(m)),t=e.settings;h(nJ(t)),y(!1),w(e.message||`设置已保存`),(async()=>{try{let e=await L.getEnvironment({runtimeChannel:t.runtime_channel});_(e),a(t,e)}catch{a(t,null)}})()}catch(e){w(e instanceof Error?e.message:`保存设置失败`)}finally{x(!1)}}async function Zi(){if(!m)return;let e=`local-asr-${Date.now()}`,t=null;try{_e(!0),pe(`正在安装本地语音识别环境...`),he(``),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&he(n.log),n.done&&t&&(clearInterval(t),t=null)}catch{}},1500);let n=await L.installLocalAsr({installSessionId:e});t&&=(clearInterval(t),null);try{let t=await L.getInstallLog(e);t.log&&he(t.log)}catch{}pe(n.installed?`本地语音识别环境已安装`:`本地语音识别环境安装失败`);let r=n.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});if(_(r),n.installed)try{let e=await L.updateSettings({...Yi(m),transcription_provider:`local`});h(nJ(e.settings)),y(!1),w(e.message||`已切换为本地 ASR`),a(e.settings,r)}catch(e){pe(`本地 ASR 已安装,但切换默认转写方式失败:${e instanceof Error?e.message:`保存设置失败`}`)}i()}catch(e){t&&=(clearInterval(t),null),pe(e instanceof Error?e.message:`安装本地语音识别环境失败`)}finally{_e(!1)}}async function Qi(){if(!m)return;let e=`funasr-${Date.now()}`,t=null;try{Ce(!0),ye(`正在安装 FunASR 语音识别环境(含 torch 等依赖,可能需要较长时间)...`),xe(``),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&xe(n.log),n.done&&t&&(clearInterval(t),t=null)}catch(e){xe(t=>t+`\n[轮询异常: ${e instanceof Error?e.message:`network error`}]`)}},1500);let n=await L.installFunAsr({installSessionId:e});t&&=(clearInterval(t),null);try{let t=await L.getInstallLog(e);t.log&&xe(t.log)}catch{}ye(n.installed?`FunASR 语音识别环境已安装`:`FunASR 语音识别环境安装失败`);let r=n.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});if(_(r),n.installed)try{let e=await L.updateSettings({...Yi(m),transcription_provider:`funasr`});h(nJ(e.settings)),y(!1),w(e.message||`已切换为 FunASR`),a(e.settings,r)}catch(e){ye(`FunASR 已安装,但切换默认转写方式失败:${e instanceof Error?e.message:`保存设置失败`}`)}i()}catch(e){t&&=(clearInterval(t),null),ye(e instanceof Error?e.message:`安装 FunASR 语音识别环境失败`)}finally{Ce(!1)}}async function $i(){if(!m)return;let e=`knowledge-deps-${Date.now()}`,t=null;try{Le(!0),Ne(`正在安装知识库依赖...`),Fe(``),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&Fe(n.log),n.done&&t&&(clearInterval(t),t=null)}catch{}},1500);let n=await L.installKnowledgeDependencies({runtime_channel:m.runtime_channel,provider:m.knowledge_embedding_provider||`local_huggingface`,reinstall:!!yi||Ci,installSessionId:e});t&&=(clearInterval(t),null);try{let t=await L.getInstallLog(e);t.log&&Fe(t.log)}catch{}Ne(n.installed?`知识库依赖已安装并完成检测`:`知识库依赖安装后仍未完全就绪`),_(n.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0})),await ea(),i()}catch(e){t&&=(clearInterval(t),null),Ne(e instanceof Error?e.message:`安装知识库依赖失败`)}finally{Le(!1)}}async function ea(){if(m)try{ze(await L.getKnowledgeRequirements(m.knowledge_embedding_provider||`local_huggingface`))}catch(e){console.error(`Failed to fetch knowledge requirements:`,e)}}async function ta(){_(await L.getEnvironment({runtimeChannel:m?.runtime_channel,refresh:!0})),await ea(),i()}async function na(){if(!m)return;let e=`emb-dl-${Date.now()}`;try{Ve(!0),Ye(!1),qe(``),Ge(`正在安装依赖并下载模型...`);let t=await L.downloadEmbeddingModel({provider:m.knowledge_embedding_provider||`local_huggingface`,model:m.knowledge_embedding_model,hf_endpoint:m.hf_endpoint,installSessionId:e});try{qe((await L.getInstallLog(e)).log||t.stdoutTail||``)}catch{qe(t.stdoutTail||``)}Ge(t.downloaded?`模型下载完成,可以测试了。`:`下载失败:${t.detail}`)}catch(e){Ge(e instanceof Error?e.message:`下载模型失败`)}finally{Ve(!1)}}async function ra(){if(m)try{Ue(!0),qe(``),Ge(m.knowledge_embedding_provider===`siliconflow`?`正在请求硅基流动 Embedding API...`:`正在加载并验证 Embedding 模型...`);let e=m.knowledge_embedding_provider||`local_huggingface`,t=await L.testEmbeddingModel({provider:e,model:e===`siliconflow`?xi:m.knowledge_embedding_model,hf_endpoint:m.hf_endpoint,api_key:e===`siliconflow`&&!eJ(m.siliconflow_embedding_api_key)?m.siliconflow_embedding_api_key:void 0,base_url:e===`siliconflow`?bi:void 0});qe(t.stdoutTail||``),t.verified?(Ye(!0),Ge(t.detail||`模型验证成功!`)):(Ye(!1),Ge(`验证失败:${t.detail}`))}catch(e){Ye(!1),Ge(e instanceof Error?e.message:`验证模型失败`)}finally{Ue(!1)}}async function ia(){if(!(!m||we))try{Te(!0),ke(``),je(``);let e=window.desktop?.bilibili;if(!e){De(`正在生成 B 站扫码登录二维码...`);let e=await L.createBilibiliCookieQrcode(),t=await zq.toDataURL(e.url,{margin:1,width:180,color:{dark:`#111111`,light:`#ffffff`}});ke(e.qrcodeKey),je(t),De(`请用手机 B 站扫码,并在手机上确认登录。`);return}De(`请在新窗口登录 B 站,登录成功后会自动保存 cookies...`);let t=await e.captureLoginCookies(),n=await L.updateSettings({ytdlp_cookies_file:t.cookiesFile,ytdlp_cookies_browser:``});h(nJ(n.settings)),y(!1),w(n.message||`设置已保存`),De(`B 站登录态已保存${t.browser?`(${t.browser})`:``},捕获 ${t.cookieCount} 条 cookies。`),a(n.settings,g)}catch(e){De(e instanceof Error?e.message:`捕获 B 站登录态失败,请按教程手动导出 cookies.txt。`)}finally{Te(!1)}}function aa(e){if(!m)return null;if(e===`main`)return{llm_enabled:m.llm_enabled,llm_provider:m.llm_provider,llm_base_url:m.llm_base_url,llm_model:m.llm_model,...m.llm_api_key.trim()&&!eJ(m.llm_api_key)?{llm_api_key:m.llm_api_key}:{}};let t=String(m.visual_evidence_api_key||``).trim(),n=String(m.llm_api_key||``).trim();return{llm_test_scope:`visual`,llm_enabled:m.visual_multimodal_enabled,llm_provider:m.visual_vlm_provider||m.llm_provider,llm_base_url:m.visual_evidence_base_url||m.llm_base_url,llm_model:m.visual_evidence_model||m.llm_model,...!t||eJ(t)?n&&!eJ(n)?{llm_api_key:n}:{}:{llm_api_key:t}}}async function oa(e){let t=aa(e);if(!t)throw Error(`模型配置尚未加载。`);return L.testLlmConnection(t)}async function sa(){if(!(!m||St))try{Ct(!0),xt(e=>e+1),yt(`正在测试 LLM 连接与 JSON 输出...`);let e=await oa(`main`),t=e.jsonPreview||e.responsePreview,n=t?`,示例:${t}`:``;yt(`${e.message}${n}`),Tt(t=>({...t,main:{status:`available`,message:e.message}}))}catch(e){let t=e instanceof Error?e.message:`LLM 连接测试失败`;yt(t),Tt(e=>({...e,main:{status:`unavailable`,message:t}}))}finally{Ct(!1)}}async function ca(){if(!(!m||St))try{Ct(!0),xt(e=>e+1),yt(`正在测试知识库 LLM 连接与 JSON 输出...`);let e=await L.testLlmConnection({llm_test_scope:`knowledge`,llm_enabled:m.knowledge_llm_enabled,llm_provider:m.knowledge_llm_provider,llm_base_url:m.knowledge_llm_base_url,llm_model:m.knowledge_llm_model,...m.knowledge_llm_api_key.trim()&&!eJ(m.knowledge_llm_api_key)?{llm_api_key:m.knowledge_llm_api_key}:{}}),t=e.jsonPreview||e.responsePreview,n=t?`,示例:${t}`:``;yt(`${e.message}${n}`)}catch(e){yt(e instanceof Error?e.message:`知识库 LLM 连接测试失败`)}finally{Ct(!1)}}async function la(){if(!(!m||St))try{Ct(!0),xt(e=>e+1),yt(`正在测试视觉模型连接与 JSON 输出...`);let e=await oa(`visual`),t=e.jsonPreview||e.responsePreview,n=t?`,示例:${t}`:``;yt(`${e.message}${n}`),Tt(t=>({...t,visual:{status:`available`,message:e.message}}))}catch(e){let t=e instanceof Error?e.message:`视觉模型连接测试失败`;yt(t),Tt(e=>({...e,visual:{status:`unavailable`,message:t}}))}finally{Ct(!1)}}function ua(){let e=Ht;Ut(null),e&&da(e)}async function da(e){if(!m||St)return;let t=sn.current+1;sn.current=t,Tt(t=>({...t,[e]:{status:`checking`,message:``}}));try{let n=await oa(e);if(sn.current!==t)return;Tt(t=>({...t,[e]:{status:`available`,message:n.message}}))}catch(n){if(sn.current!==t)return;Tt(t=>({...t,[e]:{status:`unavailable`,message:n instanceof Error?n.message:`模型不可用`}}))}}async function fa(){if(!(!m||gt))try{_t(!0),ht(`正在测试 ASR 连接...`);let e=await L.testAsrConnection({transcription_provider:m.transcription_provider,siliconflow_asr_base_url:m.siliconflow_asr_base_url,siliconflow_asr_model:m.siliconflow_asr_model,...m.siliconflow_asr_api_key.trim()&&!eJ(m.siliconflow_asr_api_key)?{siliconflow_asr_api_key:m.siliconflow_asr_api_key}:{},multimodal_asr_base_url:m.multimodal_asr_base_url,multimodal_asr_model:m.multimodal_asr_model,...m.multimodal_asr_api_key.trim()&&!eJ(m.multimodal_asr_api_key)?{multimodal_asr_api_key:m.multimodal_asr_api_key}:{}}),t=e.responsePreview?`,示例:${e.responsePreview}`:``;ht(`${e.message}${t}`)}catch(e){ht(e instanceof Error?e.message:`ASR 连接测试失败`)}finally{_t(!1)}}let pa=$n(m,g);function V(e){return t=>{rn.current[e]=t}}function ma(e,t){Ft(e),Lt(t),Gt(``)}function ha(e){return m?e===`siliconflow_asr_api_key`?{category:`transcription`,targetKey:`siliconflow_asr_api_key`}:e===`multimodal_asr_base_url`?{category:`transcription`,targetKey:`multimodal_asr_base_url`}:e===`local_asr_runtime`?{category:`runtime`,targetKey:`local_asr_runtime`}:e===`auto_mindmap_requires_llm`?{category:`generation`,targetKey:`llm_enabled`}:e===`knowledge_dependencies`?{category:`runtime`,targetKey:`knowledge_runtime`}:e===`siliconflow_embedding_api_key`?{category:`knowledge`,targetKey:`siliconflow_embedding_api_key`}:e===`knowledge_llm_configuration`?String(m.knowledge_llm_mode||`same_as_main`).trim().toLowerCase()===`custom`?m.knowledge_llm_enabled?String(m.knowledge_llm_base_url||``).trim()?tJ(m.knowledge_llm_api_key,m.knowledge_llm_api_key_configured)?String(m.knowledge_llm_model||``).trim()?{category:`knowledge`,targetKey:`knowledge_llm_base_url`}:{category:`knowledge`,targetKey:`knowledge_llm_model`}:{category:`knowledge`,targetKey:`knowledge_llm_api_key`}:{category:`knowledge`,targetKey:`knowledge_llm_base_url`}:{category:`knowledge`,targetKey:`knowledge_llm_enabled`}:m.llm_enabled?String(m.llm_base_url||``).trim()?tJ(m.llm_api_key,m.llm_api_key_configured)?String(m.llm_model||``).trim()?{category:`knowledge`,targetKey:`knowledge_llm_mode`}:{category:`generation`,targetKey:`llm_model`}:{category:`generation`,targetKey:`llm_api_key`}:{category:`generation`,targetKey:`llm_base_url`}:{category:`generation`,targetKey:`llm_enabled`}:e===`llm_configuration`?String(m.llm_base_url||``).trim()?tJ(m.llm_api_key,m.llm_api_key_configured)?String(m.llm_model||``).trim()?{category:`generation`,targetKey:`llm_base_url`}:{category:`generation`,targetKey:`llm_model`}:{category:`generation`,targetKey:`llm_api_key`}:{category:`generation`,targetKey:`llm_base_url`}:e===`ytdlp_cookies_browser`||e===`ytdlp_cookies_file`?{category:`video`,targetKey:`ytdlp_cookies_file`}:null:null}return(0,R.jsxs)(`div`,{className:`settings-page-wrapper`,children:[(0,R.jsx)(Vx,{notices:[{id:`settings-save-status`,message:C},{id:`settings-cuda-status`,message:T},{id:`settings-local-asr-status`,message:fe},{id:`settings-funasr-status`,message:ve},{id:`settings-knowledge-deps-status`,message:Me},{id:`settings-runtime-status`,message:nt},{id:`settings-asr-test-status`,message:mt},{id:`settings-llm-test-status`,message:vt,version:bt},{id:`settings-storage-status`,message:Mt},{id:`settings-backend-error`,message:t.backend?.lastError||``,tone:`error`},{id:`settings-service-status`,message:ft}]}),(0,R.jsxs)(`aside`,{className:`settings-nav`,ref:en,children:[(0,R.jsxs)(`div`,{className:`settings-nav-header`,children:[(0,R.jsx)(`span`,{className:`settings-nav-label-small`,children:`BiliSum`}),(0,R.jsxs)(`div`,{className:`settings-nav-brand-card`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-brand-copy`,children:[(0,R.jsx)(`span`,{className:`settings-nav-brand-kicker`,children:`设置`}),(0,R.jsx)(`strong`,{children:`管理应用与运行配置`}),(0,R.jsx)(`p`,{children:`调整目录、模型、服务与环境配置。`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-brand-metrics`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-metric`,children:[(0,R.jsx)(`span`,{children:`服务`}),(0,R.jsx)(`strong`,{children:wr?`在线`:Sr?`启动中`:`离线`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-metric`,children:[(0,R.jsx)(`span`,{children:`设备`}),(0,R.jsx)(`strong`,{children:Zn(m.whisper_device)})]})]})]})]}),(0,R.jsxs)(`div`,{className:`settings-nav-list`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-group`,children:[(0,R.jsx)(`span`,{className:`settings-nav-group-label`,children:`工作流`}),(0,R.jsx)(`nav`,{className:`settings-nav-links`,children:Or.map(e=>(0,R.jsxs)(`button`,{className:`settings-nav-item ${Pt===e.id?`active`:``}`,type:`button`,onClick:()=>Ft(e.id),children:[(0,R.jsx)(`span`,{className:`settings-nav-icon`,children:e.icon}),(0,R.jsxs)(`span`,{className:`settings-nav-copy`,children:[(0,R.jsx)(`span`,{className:`settings-nav-label`,children:e.label}),(0,R.jsx)(`span`,{className:`settings-nav-description`,children:e.description})]})]},e.id))})]}),(0,R.jsxs)(`div`,{className:`settings-nav-group`,children:[(0,R.jsx)(`span`,{className:`settings-nav-group-label`,children:`系统`}),(0,R.jsx)(`nav`,{className:`settings-nav-links`,children:kr.map(e=>(0,R.jsxs)(`button`,{className:`settings-nav-item ${Pt===e.id?`active`:``}`,type:`button`,onClick:()=>Ft(e.id),children:[(0,R.jsx)(`span`,{className:`settings-nav-icon`,children:e.icon}),(0,R.jsxs)(`span`,{className:`settings-nav-copy`,children:[(0,R.jsx)(`span`,{className:`settings-nav-label`,children:e.label}),(0,R.jsx)(`span`,{className:`settings-nav-description`,children:e.description})]})]},e.id))})]})]}),(0,R.jsxs)(`div`,{className:`settings-nav-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button settings-save-btn`,type:`button`,disabled:b||!v,onClick:async e=>{e.preventDefault(),await Xi(e)},children:b?`保存中...`:v?`保存设置`:`已保存`}),(0,R.jsxs)(`div`,{className:`settings-nav-summary`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`运行环境`}),(0,R.jsx)(`strong`,{children:g?.runtimeChannel||m.runtime_channel||`base`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`LLM`}),(0,R.jsx)(`strong`,{children:Vr?`已配置`:m.llm_enabled?`待补全`:`关闭`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`自动导图`}),(0,R.jsx)(`strong`,{children:m.auto_generate_mindmap?`开启`:`关闭`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`知识库`}),(0,R.jsx)(`strong`,{children:m.knowledge_enabled?Si&&yi?`就绪`:`待配置`:`关闭`})]})]})]})]}),(0,R.jsx)(`main`,{className:`settings-content`,children:(0,R.jsxs)(`div`,{className:`settings-content-scroll`,ref:tn,children:[(0,R.jsxs)(`section`,{className:`settings-search-panel`,"aria-label":`搜索设置`,children:[(0,R.jsxs)(`div`,{className:`settings-search-box`,children:[(0,R.jsx)(Nr,{className:`settings-search-icon`,"aria-hidden":`true`}),(0,R.jsx)(`input`,{className:`settings-search-input`,type:`search`,value:Wt,onChange:e=>Gt(e.target.value),placeholder:`搜索设置,例如 API Key、输出目录、知识笔记、并发、Cookies`}),Wt?(0,R.jsx)(`button`,{className:`settings-search-clear`,type:`button`,onClick:()=>Gt(``),children:`清空`}):null]}),Ar?(0,R.jsx)(`div`,{className:`settings-search-results`,role:`listbox`,"aria-label":`设置搜索结果`,children:Mr.length?Mr.map(e=>(0,R.jsxs)(`button`,{className:`settings-search-result`,type:`button`,role:`option`,onClick:()=>ma(e.category,e.targetKey),children:[(0,R.jsxs)(`span`,{className:`settings-search-result-main`,children:[(0,R.jsx)(`strong`,{children:e.title}),(0,R.jsx)(`span`,{children:e.description})]}),(0,R.jsx)(`span`,{className:`settings-search-result-category`,children:e.categoryLabel})]},`${e.category}:${e.targetKey}`)):(0,R.jsx)(`div`,{className:`settings-search-empty`,children:`没有找到相关设置,换个关键词试试。`})}):null]}),(0,R.jsxs)(`header`,{className:`settings-page-hero`,children:[(0,R.jsxs)(`div`,{className:`settings-page-hero-copy`,children:[(0,R.jsx)(`span`,{className:`settings-page-kicker`,children:`Settings`}),(0,R.jsx)(`h1`,{children:Dr.label}),(0,R.jsx)(`p`,{children:Dr.description})]}),(0,R.jsxs)(`div`,{className:`settings-page-hero-meta`,children:[(0,R.jsx)(`span`,{className:`settings-hero-chip ${wr?`is-success`:Sr?`is-warning`:`is-danger`}`,children:wr?`服务在线`:Sr?`启动中...`:`服务离线`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${pa.hasBlockingIssues?`is-danger`:pa.isConfigured?`is-success`:`is-warning`}`,children:pa.hasBlockingIssues?`配置缺失`:pa.isConfigured?`配置完整`:`配置待补全`}),(0,R.jsx)(`span`,{className:`settings-hero-chip`,children:g?.runtimeChannel||m.runtime_channel||`base`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${(m.transcription_provider===`funasr`?m.funasr_device===`cuda`:g?.cudaAvailable)?`is-success`:``}`,children:m.transcription_provider===`funasr`?m.funasr_device===`cuda`?`GPU (CUDA)`:`CPU`:m.transcription_provider===`local`?Zn(m.whisper_device):g?.cudaAvailable?`CUDA Ready`:`CPU Only`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${Vr?`is-success`:``}`,children:Vr?`LLM 已配置`:m.llm_enabled?`LLM 待补全`:`LLM 关闭`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${m.knowledge_enabled&&Si&&yi?`is-success`:m.knowledge_enabled&&g?.runtimeReady!==void 0?`is-warning`:``}`,children:!g?.runtimeReady&&!g?.runtimeError?`检测中...`:m.knowledge_enabled?Si&&yi?`知识库就绪`:`知识库待配置`:`知识库关闭`})]})]}),pa.checked?(0,R.jsxs)(`section`,{className:`settings-config-health-card tone-${pa.state}`,children:[(0,R.jsxs)(`div`,{className:`settings-config-health-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`Setup Health`}),(0,R.jsx)(`h3`,{children:pa.hasBlockingIssues?`先补全关键配置,再开始处理视频`:pa.isConfigured?`当前配置状态良好`:`建议补全增强能力配置`}),(0,R.jsx)(`p`,{children:pa.summary})]}),pa.isConfigured?null:(0,R.jsx)(`div`,{className:`settings-config-health-list`,children:pa.issues.map(e=>(0,R.jsxs)(`button`,{className:`settings-config-health-item`,type:`button`,onClick:()=>zi(e.key),children:[(0,R.jsx)(`strong`,{children:e.title}),(0,R.jsx)(`span`,{children:e.description})]},e.key))})]}):null,Pt===`overview`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`设置总览`}),(0,R.jsx)(`p`,{children:`查看当前配置、运行状态和常用操作。`})]}),(0,R.jsxs)(`div`,{className:`settings-story-card`,children:[(0,R.jsxs)(`div`,{className:`settings-story-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`概览`}),(0,R.jsx)(`h3`,{children:`当前配置与运行状态`}),(0,R.jsx)(`p`,{children:`这里展示运行环境、模型、摘要模式和服务状态。排障时请切换到环境检测或日志。`})]}),(0,R.jsxs)(`div`,{className:`settings-story-stats`,children:[(0,R.jsxs)(`div`,{className:`settings-story-stat`,children:[(0,R.jsx)(`span`,{children:`服务端口`}),(0,R.jsxs)(`strong`,{children:[m.host,`:`,m.port]})]}),(0,R.jsxs)(`div`,{className:`settings-story-stat`,children:[(0,R.jsx)(`span`,{children:`转写`}),(0,R.jsx)(`strong`,{children:m.transcription_provider===`siliconflow`?`SiliconFlow API`:m.transcription_provider===`funasr`?`FunASR`:m.transcription_provider===`multimodal`?`多模态 ASR`:`Whisper 转写`})]}),(0,R.jsxs)(`div`,{className:`settings-story-stat`,children:[(0,R.jsx)(`span`,{children:`摘要模式`}),(0,R.jsx)(`strong`,{children:m.summary_mode===`llm`?`LLM 智能摘要`:`抽取式摘要`})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-grid`,children:[(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsxs)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,R.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,R.jsx)(`path`,{d:`M12 6v6l4 2`})]})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`服务状态`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${wr?`text-success`:`text-danger`}`,children:wr?`运行中`:`已停止`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsxs)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,R.jsx)(`rect`,{x:`2`,y:`3`,width:`20`,height:`14`,rx:`2`}),(0,R.jsx)(`line`,{x1:`8`,y1:`21`,x2:`16`,y2:`21`})]})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`运行环境`}),(0,R.jsx)(`strong`,{className:`overview-status-value`,children:g?.runtimeChannel||m.runtime_channel||`base`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsx)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,R.jsx)(`polyline`,{points:`22 12 18 12 15 21 9 3 6 12 2 12`})})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`推理设备`}),(0,R.jsx)(`strong`,{className:`overview-status-value`,children:m.transcription_provider===`local`?Zn(m.whisper_device):m.transcription_provider===`funasr`?Zn(m.funasr_device):`云端识别`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsx)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,R.jsx)(`path`,{d:`M20.2 7.8l-7.7 7.7a4 4 0 0 1-5.7 0l-3-3a1 1 0 0 1 1.4-1.4l3 3a2 2 0 0 0 2.8 0l7.7-7.7a1 1 0 0 1 1.4 1.4z`})})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`LLM 摘要`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${m.llm_enabled?`text-success`:``}`,children:m.llm_enabled?`已启用`:`已关闭`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsx)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,R.jsx)(`path`,{d:`M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z`})})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`语音识别服务`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${ii?`text-success`:`text-danger`}`,children:m.transcription_provider===`siliconflow`?ii?`硅基流动已配置`:`硅基流动待补全`:m.transcription_provider===`multimodal`?ii?`多模态 ASR 已配置`:`多模态 ASR 待补全`:m.transcription_provider===`funasr`?ui?`FunASR 已安装`:`FunASR 未安装`:vi?`Whisper 已安装`:`Whisper 未安装`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsxs)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,R.jsx)(`path`,{d:`M4 5h16`}),(0,R.jsx)(`path`,{d:`M4 12h10`}),(0,R.jsx)(`path`,{d:`M4 19h16`}),(0,R.jsx)(`circle`,{cx:`18`,cy:`12`,r:`2`})]})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`自动导图`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${ni?`text-success`:``}`,children:ni?`已启用`:`已关闭`})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-section`,children:[(0,R.jsx)(`h3`,{className:`overview-section-title`,children:`环境信息`}),(0,R.jsxs)(`div`,{className:`overview-info-grid`,children:[(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`Python`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:g?.pythonVersion||`-`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`Torch`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.torchInstalled?`text-success`:``}`,children:g?.torchInstalled?g?.torchVersion||`已安装`:`未安装`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`GPU`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.cudaAvailable?`text-success`:``}`,children:g?.cudaAvailable?g?.gpuName||`已就绪`:`未检测到`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`yt-dlp`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:g?.ytDlpVersion||`-`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:m.transcription_provider===`funasr`?`FunASR`:`Whisper`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.localAsrInstalled?`text-success`:``}`,children:g?.localAsrInstalled?g?.localAsrVersion||`已安装`:`未安装`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`FFmpeg`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.ffmpegLocation?`text-success`:``}`,children:g?.ffmpegLocation?`已安装`:`未安装`})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-section`,children:[(0,R.jsx)(`h3`,{className:`overview-section-title`,children:`版本信息`}),(0,R.jsxs)(`div`,{className:`overview-info-grid`,children:[(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`应用版本`}),(0,R.jsxs)(`span`,{className:`overview-info-value`,children:[`v`,t.version||`-`]})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`监听地址`}),(0,R.jsxs)(`span`,{className:`overview-info-value`,children:[m.host,`:`,m.port]})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`语言`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:m.language===`zh`?`中文`:m.language===`en`?`English`:`日本語`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`ASR 模型`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:m.transcription_provider===`local`?m.fixed_model:m.transcription_provider===`multimodal`?m.multimodal_asr_model:m.siliconflow_asr_model})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-section`,children:[(0,R.jsx)(`h3`,{className:`overview-section-title`,children:`快速操作`}),(0,R.jsxs)(`div`,{className:`overview-actions`,children:[(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`runtime`),children:`运行环境维护`}),(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`logs`),children:`查看日志`}),(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`transcription`),children:`转写设置`}),(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`generation`),children:`摘要设置`})]})]})]}),Pt===`files`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`输出与文件`}),(0,R.jsx)(`p`,{children:`管理导出位置、应用数据目录和本地空间占用。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`data_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`数据目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.data_dir),onChange:e=>B({...m,data_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`存储视频摘要和元数据`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`cache_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`缓存目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.cache_dir),onChange:e=>B({...m,cache_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`临时缓存文件`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`tasks_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`任务目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.tasks_dir),onChange:e=>B({...m,tasks_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`任务历史记录`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`output_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`输出目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.output_dir),onChange:e=>B({...m,output_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`手动导出的 Markdown / Obsidian 笔记会写入这里。`})]})]})]}),Pt===`files`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`文件管理`}),(0,R.jsx)(`p`,{children:`查看本地空间占用,并安全清理缓存和孤儿任务目录。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-overview`,ref:V(`storage_cleanup`),children:[(0,R.jsxs)(`div`,{className:`settings-update-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`Storage`}),(0,R.jsx)(`h3`,{children:`当前本地占用`}),(0,R.jsxs)(`p`,{children:[`已托管空间约 `,aJ(Et?.totals.managedBytes||0),`, 共 `,oJ(Et?.totals.managedFiles||0,`文件`),`,`,oJ(Et?.totals.managedDirectories||0,`目录`),`。`]})]}),(0,R.jsxs)(`div`,{className:`settings-update-badges`,children:[(0,R.jsx)(`span`,{className:`helper-chip`,children:Ot?`扫描中...`:`统计已就绪`}),(0,R.jsx)(`span`,{className:`helper-chip ${Ii?`status-success`:`status-pending`}`,children:Ii?`可校验引用关系`:`服务离线,禁用清理`}),(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`可回收 `,aJ(Li)]})]})]}),(0,R.jsx)(`div`,{className:`settings-storage-grid`,children:(Et?.directories||[]).map(e=>(0,R.jsxs)(`article`,{className:`settings-storage-card`,children:[(0,R.jsxs)(`div`,{className:`settings-storage-card-head`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:e.label}),(0,R.jsx)(`strong`,{children:aJ(e.sizeBytes)})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>void yr(e.key),children:`打开目录`})]}),(0,R.jsx)(`p`,{className:`settings-storage-path`,children:e.path}),(0,R.jsxs)(`div`,{className:`settings-storage-meta`,children:[(0,R.jsx)(`span`,{children:e.exists?`目录存在`:`目录不存在`}),(0,R.jsx)(`span`,{children:oJ(e.fileCount,`文件`)}),(0,R.jsx)(`span`,{children:oJ(e.directoryCount,`子目录`)})]})]},e.key))}),(0,R.jsxs)(`div`,{className:`settings-storage-detail-grid`,children:[(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`缓存目录`}),(0,R.jsx)(`strong`,{children:aJ(Ni?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:"当前仅把 `uploads` 和 `covers` 视为可安全回收的缓存内容,删除后必要资源会自动重新生成。"}),(0,R.jsxs)(`div`,{className:`settings-storage-meta`,children:[(0,R.jsx)(`span`,{children:oJ(Et?.cleanup.cacheCandidateCount||0,`可清理项`)}),(0,R.jsxs)(`span`,{children:[`预计释放 `,aJ(Et?.cleanup.cacheCandidateBytes||0)]})]})]}),(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`任务结果`}),(0,R.jsx)(`strong`,{children:aJ(Pi?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:`仅识别目录名像任务 ID、但数据库中已不存在的孤儿任务目录,不会删除仍被引用的结果文件。`}),(0,R.jsxs)(`div`,{className:`settings-storage-meta`,children:[(0,R.jsx)(`span`,{children:oJ(Et?.cleanup.orphanTaskCount||0,`孤儿目录`)}),(0,R.jsxs)(`span`,{children:[`预计释放 `,aJ(Et?.cleanup.orphanTaskBytes||0)]})]})]}),(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`日志目录`}),(0,R.jsx)(`strong`,{children:aJ(z?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:`日志仅展示体积和位置,首版不提供清空操作,避免误删排障信息。`})]}),(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`运行环境目录`}),(0,R.jsx)(`strong`,{children:aJ(Fi?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:`运行环境目录只做统计,不参与清理,避免影响 Python、Torch 或 CUDA 运行环境。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-update-next-step`,children:[(0,R.jsx)(`strong`,{children:`清理说明`}),(0,R.jsx)(`span`,{children:Ii?Ri>0?`预计可安全清理 ${Ri} 项内容,释放约 ${aJ(Li)}。`:`当前没有发现可安全清理的缓存或孤儿任务目录。`:`当前服务离线,无法确认哪些任务目录仍被数据库引用,因此已禁用一键清理。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:Ot||At,onClick:()=>void vr(),children:Ot?`扫描中...`:`刷新统计`}),(0,R.jsx)(`button`,{className:`secondary-button danger-button`,type:`button`,disabled:!Ii||At||Ot,onClick:()=>void br(),children:At?`清理中...`:`一键清理孤儿项`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>void yr(`data`),children:`打开数据目录`})]})]}),Pt===`video`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`视频获取`}),(0,R.jsx)(`p`,{children:`处理 B 站登录态、下载缓存和转写临时音频。遇到风控、登录或重复下载问题时先看这里。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`ytdlp_cookies_file`?`is-highlighted`:``}`,ref:V(`ytdlp_cookies_file`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`B 站 Cookies 文件`}),(0,R.jsxs)(`div`,{className:`settings-input-action-row`,children:[(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.ytdlp_cookies_file||``,onChange:e=>B({...m,ytdlp_cookies_file:e.target.value}),placeholder:`C:\\\\Users\\\\you\\\\Downloads\\\\cookies.txt`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:we,onClick:()=>void ia(),children:we?`获取中...`:`登录获取`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`推荐通过提示弹窗打开 B 站登录窗口自动生成;也可以手动填写从已登录浏览器导出的 cookies.txt。`}),Ae?(0,R.jsxs)(`div`,{className:`settings-cookie-qrcode`,children:[(0,R.jsx)(`img`,{src:Ae,alt:`B 站扫码登录二维码`}),(0,R.jsx)(`span`,{children:`用手机 B 站扫码确认后会自动写入 cookies 文件。`})]}):null,Ee?(0,R.jsx)(`span`,{className:`settings-input-caption`,children:Ee}):null]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`enable_cache`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用下载缓存`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.enable_cache?`true`:`false`,onChange:e=>B({...m,enable_cache:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`true`,children:`开启`}),(0,R.jsx)(`option`,{value:`false`,children:`关闭`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`开启后会复用封面、上传文件和部分中间结果,适合反复处理同一批视频。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`preserve_temp_audio`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`保留临时音频`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.preserve_temp_audio?`true`:`false`,onChange:e=>B({...m,preserve_temp_audio:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`不保留`}),(0,R.jsx)(`option`,{value:`true`,children:`保留`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`排查转写问题时可以临时开启;日常关闭能减少磁盘占用。`})]})]})]}),Pt===`transcription`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`语音转文字`}),(0,R.jsx)(`p`,{children:`配置视频音频如何转成文本:云端 ASR 更省心,本地 ASR 更依赖运行环境和设备。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`转写方式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,ref:V(`transcription_provider`),value:m.transcription_provider,onChange:e=>B({...m,transcription_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`siliconflow`,children:`硅基流动 API`}),(0,R.jsx)(`option`,{value:`multimodal`,children:`多模态 ASR(第三方)`}),(0,R.jsxs)(`option`,{value:`funasr`,disabled:!ui,children:[`FunASR(本地)`,ui?``:`(需先安装)`]}),(0,R.jsx)(`option`,{value:`local`,disabled:!vi,children:`Whisper 转写(需先安装)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`默认推荐云端模式(硅基流动的语音识别是免费的!只需要注册然后填上apikey就可以用了)。`})]}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`优先使用 UP 主字幕`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`开启后,BiliSum 会尝试从 B 站 API 获取视频自带字幕(CC 字幕、UP 主上传字幕)。如果字幕存在且完整,将跳过 ASR 转写,节省时间。字幕不存在时自动使用 ASR。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:m.prefer_bilibili_subtitle||!1,onChange:e=>B({...m,prefer_bilibili_subtitle:e.target.checked})}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),di?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`siliconflow_asr_base_url`?`is-highlighted`:``}`,ref:V(`siliconflow_asr_base_url`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`SiliconFlow Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_asr_base_url,onChange:e=>B({...m,siliconflow_asr_base_url:e.target.value}),placeholder:`https://api.siliconflow.cn/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:"默认保持 `https://api.siliconflow.cn/v1` 即可。"})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`siliconflow_asr_api_key`?`is-highlighted`:``}`,ref:V(`siliconflow_asr_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`SiliconFlow API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.siliconflow_asr_api_key,onFocus:rJ,onChange:e=>B({...m,siliconflow_asr_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(qq,{})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`siliconflow_asr_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`语音转写 ASR 模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_asr_model,onChange:e=>B({...m,siliconflow_asr_model:e.target.value}),placeholder:`TeleAI/TeleSpeechASR`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`推荐使用:TeleAI/TeleSpeechASR`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`siliconflow_asr_chunk_duration_seconds`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`ASR 切片时长(秒)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:60,max:3600,value:m.siliconflow_asr_chunk_duration_seconds??1800,onChange:e=>B({...m,siliconflow_asr_chunk_duration_seconds:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`长音频按此时长切片,默认 1800 秒(30 分钟)。API 单次最长 60 分钟。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`siliconflow_asr_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`ASR 并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,max:8,value:m.siliconflow_asr_concurrency??2,onChange:e=>B({...m,siliconflow_asr_concurrency:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`同时发送的转写请求数,默认 2。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:gt,onClick:()=>void fa(),children:gt?`测试中...`:`测试 ASR 是否可用`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用当前表单中的 SiliconFlow Base URL、API Key 和 ASR 模型名发起一次临时转写测试,不会保存设置。`})]})]}):fi?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`multimodal_asr_base_url`?`is-highlighted`:``}`,ref:V(`multimodal_asr_base_url`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态 ASR Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.multimodal_asr_base_url,onChange:e=>B({...m,multimodal_asr_base_url:e.target.value}),placeholder:`https://api.example.com/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`支持 OpenAI 兼容的多模态 API 地址。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`multimodal_asr_api_key`?`is-highlighted`:``}`,ref:V(`multimodal_asr_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态 ASR API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.multimodal_asr_api_key,onFocus:rJ,onChange:e=>B({...m,multimodal_asr_api_key:e.target.value}),placeholder:`sk-...`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`multimodal_asr_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态 ASR 模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.multimodal_asr_model,onChange:e=>B({...m,multimodal_asr_model:e.target.value}),placeholder:`mimo-v2-omni`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用支持音频输入的多模态模型进行语音转文字。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`multimodal_asr_chunk_duration_seconds`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态切片时长(秒)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:30,max:600,value:m.multimodal_asr_chunk_duration_seconds??180,onChange:e=>B({...m,multimodal_asr_chunk_duration_seconds:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`长音频自动切片时每段的秒数,默认 180 秒(3 分钟)。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`multimodal_asr_max_retries`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态切片重试次数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:0,max:10,value:m.multimodal_asr_max_retries??5,onChange:e=>B({...m,multimodal_asr_max_retries:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`每段切片返回空时最多重试几次,默认 5 次。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:gt,onClick:()=>void fa(),children:gt?`测试中...`:`测试 ASR 是否可用`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用当前表单中的多模态配置发起一次临时转写测试,不会保存设置。`})]})]}):pi?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`FunASR 模型`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_model,onChange:e=>B({...m,funasr_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:`paraformer-zh`,children:`paraformer-zh(中文通用,推荐)`}),(0,R.jsx)(`option`,{value:`iic/SenseVoiceSmall`,children:`SenseVoice-Small(多语言)`}),(0,R.jsx)(`option`,{value:`iic/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404-pytorch`,children:`SEACO Paraformer(高级,带时间戳)`}),(0,R.jsx)(`option`,{value:`FunAudioLLM/Fun-ASR-Nano-2512`,children:`Fun-ASR-Nano(轻量级)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择 FunASR 语音识别模型`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_device`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`运行设备`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_device,onChange:e=>B({...m,funasr_device:e.target.value}),children:[(0,R.jsx)(`option`,{value:`cpu`,children:`CPU`}),(0,R.jsx)(`option`,{value:`cuda`,children:`GPU (CUDA)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择推理设备,GPU 需要 CUDA 支持`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_vad_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`语音活动检测 (VAD)`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_vad_model,onChange:e=>B({...m,funasr_vad_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:``,children:`关闭`}),(0,R.jsx)(`option`,{value:`fsmn-vad`,children:`开启(fsmn-vad)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`启用语音活动检测以提高识别准确度`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_punc_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动标点`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_punc_model,onChange:e=>B({...m,funasr_punc_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:``,children:`关闭`}),(0,R.jsx)(`option`,{value:`ct-punc`,children:`开启(ct-punc)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`自动添加标点符号`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_spk_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`说话人识别`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_spk_model,onChange:e=>B({...m,funasr_spk_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:``,children:`关闭`}),(0,R.jsx)(`option`,{value:`cam++`,children:`开启(cam++)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`识别不同说话人`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_hub`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型下载源`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_hub,onChange:e=>B({...m,funasr_hub:e.target.value}),children:[(0,R.jsx)(`option`,{value:`ms`,children:`ModelScope`}),(0,R.jsx)(`option`,{value:`hf`,children:`HuggingFace`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择模型下载源`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_hotword`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`热词(可选)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.funasr_hotword,onChange:e=>B({...m,funasr_hotword:e.target.value}),placeholder:`多个热词用空格分隔`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`提高特定词汇的识别准确度,多个热词用空格分隔`})]}),(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`可用性状态`}),(0,R.jsx)(`div`,{className:`settings-status-display`,children:ui?(0,R.jsxs)(`span`,{className:`text-success`,children:[`✅ FunASR 已安装`,g?.funasrVersion?`(${g.funasrVersion})`:``]}):(0,R.jsx)(`span`,{className:`text-danger`,children:`❌ FunASR 未安装 — 请前往「运行环境」板块安装`})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:ui?`FunASR 环境就绪,可直接使用。`:`FunASR 依赖需要单独安装。前往「运行环境」→「FunASR 运行环境」点击安装按钮,安装完成后会自动切换。`})]})]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`device_preference`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`推理设备`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:Xn(m.device_preference),onChange:e=>B({...m,device_preference:e.target.value}),children:[(0,R.jsx)(`option`,{value:`auto`,children:`自动选择`}),(0,R.jsx)(`option`,{value:`cuda`,children:`GPU (CUDA)`}),(0,R.jsx)(`option`,{value:`cpu`,children:`CPU`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择推理设备,GPU 需要 CUDA 支持`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型模式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.model_mode,onChange:e=>B({...m,model_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`fixed`,children:`固定模型`}),(0,R.jsx)(`option`,{value:`auto`,children:`自动选择`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`自动模式会根据设备选择最优模型`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`fixed_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`固定模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.fixed_model,onChange:e=>B({...m,fixed_model:e.target.value}),placeholder:`tiny / base / small / medium / large-v3`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`Whisper 模型名称,小模型速度快但精度低`})]})]})]})]}),Pt===`generation`&&(0,R.jsxs)(`section`,{className:`settings-category-section generation-settings-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`摘要生成`}),(0,R.jsx)(`p`,{children:`按"基础生成、模型接入、自动产物、图文截图、长视频切块"分层管理,日常开关留在页面,密钥和模型细节放进悬浮窗。`})]}),(0,R.jsxs)(`div`,{className:`generation-settings-tree`,children:[(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`01`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`基础生成`}),(0,R.jsx)(`p`,{children:`控制摘要是否使用 LLM、输出语言和失败重试。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用 LLM 摘要`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,ref:V(`llm_enabled`),value:m.llm_enabled?`true`:`false`,onChange:e=>B({...m,llm_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用大语言模型生成更高质量的视频摘要。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要模式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.summary_mode,onChange:e=>B({...m,summary_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`llm`,children:`LLM 智能摘要`}),(0,R.jsx)(`option`,{value:`extract`,children:`仅转写`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`language`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`输出语言`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.language,onChange:e=>B({...m,language:e.target.value}),children:[(0,R.jsx)(`option`,{value:`zh`,children:`中文`}),(0,R.jsx)(`option`,{value:`en`,children:`English`}),(0,R.jsx)(`option`,{value:`ja`,children:`日本語`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_retry_count`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`重试次数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_retry_count,onChange:e=>B({...m,summary_chunk_retry_count:sJ(e.target.value,2)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`摘要 API 调用失败时的重试次数。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`02`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`模型接入`}),(0,R.jsx)(`p`,{children:`主摘要模型和视觉理解模型只展示状态,具体地址、密钥和测试放入悬浮窗。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-model-summary-grid`,children:[(0,R.jsxs)(`article`,{className:`settings-model-card settings-focus-target ${Rt===`llm_base_url`||Rt===`llm_api_key`||Rt===`llm_model`?`is-highlighted`:``}`,ref:e=>{V(`llm_base_url`)(e),V(`llm_api_key`)(e),V(`llm_model`)(e)},children:[(0,R.jsxs)(`div`,{className:`settings-model-card-top`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-model-kicker`,children:`主摘要模型`}),(0,R.jsx)(`strong`,{children:Yr})]}),(0,R.jsx)(`span`,{className:`settings-status-pill ${Jr}`,title:Wr.message||void 0,children:Kr})]}),(0,R.jsxs)(`dl`,{className:`settings-model-meta`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Provider`}),(0,R.jsx)(`dd`,{children:m.llm_provider||`openai-compatible`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Model`}),(0,R.jsx)(`dd`,{children:m.llm_model||`未填写`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Base URL`}),(0,R.jsx)(`dd`,{children:m.llm_base_url||`未填写`})]})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ut(`main`),children:`编辑与测试`})]}),(0,R.jsxs)(`article`,{className:`settings-model-card settings-focus-target ${Rt===`visual_multimodal_enabled`?`is-highlighted`:``}`,ref:V(`visual_multimodal_enabled`),children:[(0,R.jsxs)(`div`,{className:`settings-model-card-top`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-model-kicker`,children:`视觉理解模型`}),(0,R.jsx)(`strong`,{children:Qr})]}),(0,R.jsx)(`span`,{className:`settings-status-pill ${Zr}`,title:Gr.message||void 0,children:Xr})]}),(0,R.jsxs)(`dl`,{className:`settings-model-meta`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`来源`}),(0,R.jsx)(`dd`,{children:m.visual_evidence_base_url||m.visual_evidence_model||tJ(m.visual_evidence_api_key,m.visual_evidence_api_key_configured)?`独立配置`:`跟随主 LLM`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Model`}),(0,R.jsx)(`dd`,{children:m.visual_evidence_model||m.llm_model||`未填写`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Base URL`}),(0,R.jsx)(`dd`,{children:m.visual_evidence_base_url||m.llm_base_url||`未填写`})]})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ut(`visual`),children:`编辑与测试`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`03`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`自动产物`}),(0,R.jsx)(`p`,{children:`摘要完成后是否自动追加导图和图文笔记。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-visual-note-presets`,"aria-label":`知识笔记预设`,children:[(0,R.jsxs)(`button`,{type:`button`,className:`settings-visual-note-preset ${$r===`text`?`is-active`:``}`,onClick:()=>Gi(`text`),children:[(0,R.jsx)(`strong`,{children:`纯文本笔记`}),(0,R.jsx)(`span`,{children:`只生成文本知识笔记。`})]}),(0,R.jsxs)(`button`,{type:`button`,className:`settings-visual-note-preset ${$r===`visual`?`is-active`:``}`,onClick:()=>Gi(`visual`),children:[(0,R.jsx)(`strong`,{children:`无多模态的图文笔记`}),(0,R.jsx)(`span`,{children:`抽帧并按文本语义插图。`})]}),(0,R.jsxs)(`button`,{type:`button`,className:`settings-visual-note-preset ${$r===`multimodal`?`is-active`:``}`,onClick:()=>Gi(`multimodal`),children:[(0,R.jsx)(`strong`,{children:`多模态理解的图文笔记`}),(0,R.jsx)(`span`,{children:`抽帧并调用 VLM 理解画面。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`auto_generate_mindmap`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动生成思维导图`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.auto_generate_mindmap?`true`:`false`,onChange:e=>B({...m,auto_generate_mindmap:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`关闭后仍可在详情页手动生成。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`prompt_router_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Prompt 路由模式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.prompt_router_mode||`confirm`,onChange:e=>B({...m,prompt_router_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`confirm`,children:`确认后使用推荐`}),(0,R.jsx)(`option`,{value:`auto`,children:`自动套用推荐`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`首页会根据标题推荐摘要 Prompt。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_note_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`知识笔记形式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_note_mode||`text`,onChange:e=>{let t=e.target.value;B({...m,visual_note_mode:t,visual_evidence_enabled:t!==`text`,visual_evidence_use_llm:t===`vlm_integrated`,visual_multimodal_enabled:t===`vlm_integrated`})},children:[(0,R.jsx)(`option`,{value:`text`,children:`纯文本笔记`}),(0,R.jsx)(`option`,{value:`frame_insert`,children:`插图笔记`}),(0,R.jsx)(`option`,{value:`vlm_integrated`,children:`理解型图文笔记`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`纯文本不抽帧;理解型图文会调用 VLM 解析图片内容。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_evidence_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动生成图文笔记`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_evidence_enabled?`true`:`false`,disabled:(m.visual_note_mode||`text`)===`text`,onChange:e=>B({...m,visual_evidence_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`摘要完成后在独立队列生成图文版。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态理解`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_multimodal_enabled?`true`:`false`,disabled:(m.visual_note_mode||`text`)!==`vlm_integrated`,onChange:e=>B({...m,visual_multimodal_enabled:e.target.value===`true`,visual_evidence_use_llm:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭,仅按文本语义插图`}),(0,R.jsx)(`option`,{value:`true`,children:`开启,调用 VLM 理解画面`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`开启后会把压缩识别图送入视觉模型。`})]})]})]}),(m.visual_note_mode||`text`)===`text`?null:(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`04`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`图文截图`}),(0,R.jsx)(`p`,{children:`只影响图文笔记抽帧和图片质量,不影响文本总结。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_download_resolution`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`下载分辨率`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_download_resolution||`720p`,onChange:e=>B({...m,visual_download_resolution:e.target.value}),children:[(0,R.jsx)(`option`,{value:`auto`,children:`自动`}),(0,R.jsx)(`option`,{value:`360p`,children:`360p`}),(0,R.jsx)(`option`,{value:`480p`,children:`480p`}),(0,R.jsx)(`option`,{value:`720p`,children:`720p`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`只影响图文笔记抽帧视频。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`最多截图数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,max:30,value:m.visual_evidence_max_frames,onChange:e=>B({...m,visual_evidence_max_frames:sJ(e.target.value,12)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`后端限制在 1-30 张。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`截图最小间隔(秒)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:10,value:m.visual_evidence_frame_interval_seconds,onChange:e=>B({...m,visual_evidence_frame_interval_seconds:sJ(e.target.value,10)})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`笔记图片宽度`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:320,max:1600,value:m.visual_evidence_frame_width,onChange:e=>B({...m,visual_evidence_frame_width:sJ(e.target.value,960)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制最终图文笔记中的截图宽度上限。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`识别图质量`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,max:100,value:m.visual_evidence_image_quality,onChange:e=>B({...m,visual_evidence_image_quality:sJ(e.target.value,85)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`仅用于 VLM 识别压缩图。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:(m.visual_note_mode||`text`)===`text`?`04`:`05`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`Twelve Labs Pegasus 视频理解`}),(0,R.jsx)(`p`,{children:`可选。仅对本地视频生效,直接"看"画面生成理解摘要并写入知识笔记。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`twelvelabs_summary_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用 Pegasus 视频摘要`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.twelvelabs_summary_enabled?`true`:`false`,onChange:e=>B({...m,twelvelabs_summary_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`仅本地视频生效,不影响在线视频摘要流程。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Twelve Labs API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.twelvelabs_api_key||``,placeholder:`tlk_...`,autoComplete:`off`,onChange:e=>B({...m,twelvelabs_api_key:e.target.value,twelvelabs_api_key_configured:!1})}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可在 `,(0,R.jsx)(`a`,{href:`https://twelvelabs.io`,target:`_blank`,rel:`noreferrer`,children:`twelvelabs.io`}),` 免费申请。`]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Pegasus 模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`text`,value:m.twelvelabs_model||`pegasus1.5`,placeholder:`pegasus1.5`,onChange:e=>B({...m,twelvelabs_model:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`text`,value:m.twelvelabs_base_url||`https://api.twelvelabs.io/v1.3`,placeholder:`https://api.twelvelabs.io/v1.3`,onChange:e=>B({...m,twelvelabs_base_url:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Pegasus 提示词(留空用默认)`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:4,value:m.twelvelabs_prompt||``,placeholder:`留空则使用内置默认提示词`,onChange:e=>B({...m,twelvelabs_prompt:e.target.value})})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:(m.visual_note_mode||`text`)===`text`?`05`:`06`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`长视频切块`}),(0,R.jsx)(`p`,{children:`控制长视频拆分摘要的连续性和单块长度。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_target_chars`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`分块目标字符数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_target_chars,onChange:e=>B({...m,summary_chunk_target_chars:sJ(e.target.value,2200)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`LLM 处理时分块的目标字符数。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_overlap_segments`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`分块重叠段数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_overlap_segments,onChange:e=>B({...m,summary_chunk_overlap_segments:sJ(e.target.value,2)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`分块之间保留的重叠段落。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-alert info`,children:[(0,R.jsx)(`strong`,{children:`分块并发在性能页调整`}),(0,R.jsx)(`span`,{children:`如果需要控制单个任务内部同时请求的摘要块数量,请前往"性能与资源"。`})]})]})]})]})]}),Pt===`knowledge`&&(0,R.jsxs)(`section`,{className:`settings-category-section generation-settings-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`知识库与问答`}),(0,R.jsx)(`p`,{children:`知识库默认关闭,依赖按需安装到当前运行环境。按"基础开关、向量模型、LLM 配置"分层管理。`})]}),(0,R.jsxs)(`div`,{className:`generation-settings-tree`,children:[(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`01`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`基础开关`}),(0,R.jsx)(`p`,{children:`控制知识库启停、索引策略和依赖安装。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用知识库`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_enabled?`true`:`false`,onChange:e=>B({...m,knowledge_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`关闭时不会自动构建索引;标签管理仍可使用。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动维护知识库索引`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_index_auto_rebuild||`disabled`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_index_auto_rebuild:e.target.value}),children:[(0,R.jsx)(`option`,{value:`disabled`,children:`关闭自动维护`}),(0,R.jsx)(`option`,{value:`on_task_completed`,children:`视频生成结束后更新索引`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`开启知识库并安装依赖后,才会在任务完成时自动刷新索引。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`02`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`向量模型`}),(0,R.jsx)(`p`,{children:`选择 Embedding 模型的下载源和模型名。国内用户建议使用 ModelScope 源或 HuggingFace 镜像。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_embedding_provider`?`is-highlighted`:``}`,ref:V(`knowledge_embedding_provider`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型来源`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_embedding_provider||`local_huggingface`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_embedding_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`siliconflow`,children:`硅基流动在线 API`}),(0,R.jsx)(`option`,{value:`local_huggingface`,children:`本地 HuggingFace`}),(0,R.jsx)(`option`,{value:`local_modelscope`,children:`本地 ModelScope`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:m.knowledge_embedding_provider===`siliconflow`?`使用在线 API,无需本地向量模型和 GPU;索引存储仍需要 chromadb。`:`向量模型从哪个源下载和加载。`})]}),m.knowledge_embedding_provider===`siliconflow`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`siliconflow_embedding_api_key`?`is-highlighted`:``}`,ref:V(`siliconflow_embedding_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.siliconflow_embedding_api_key||``,disabled:!m.knowledge_enabled,onFocus:rJ,onChange:e=>B({...m,siliconflow_embedding_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(qq,{purpose:`embedding`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_embedding_base_url||Qq,disabled:!m.knowledge_enabled,onChange:e=>B({...m,siliconflow_embedding_base_url:e.target.value}),placeholder:`https://api.siliconflow.cn/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`硅基流动 API 端点,通常不需要修改。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_embedding_model||$q,disabled:!m.knowledge_enabled,onChange:e=>B({...m,siliconflow_embedding_model:e.target.value}),placeholder:`BAAI/bge-large-zh-v1.5`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`推荐使用 BAAI/bge-large-zh-v1.5 或 Qwen/Qwen3-Embedding-8B。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,style:{gridColumn:`1 / -1`},children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:He||!m.knowledge_enabled||!Si,onClick:()=>void ra(),children:He?`测试中...`:`测试向量模型`}),Je?(0,R.jsx)(`span`,{className:`settings-status-pill success`,children:`API 可用`}):Lr?(0,R.jsx)(`span`,{className:`settings-status-pill warning`,children:`待测试`}):null]}),We?(0,R.jsx)(`div`,{className:`settings-inline-alert ${Je?`success`:We.includes(`失败`)||We.includes(`未配置`)?`warning`:`info`}`,children:(0,R.jsx)(`span`,{children:We})}):null,Ke?(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:6,readOnly:!0,value:Ke}):null]}):m.knowledge_embedding_provider===`online`?null:(0,R.jsxs)(R.Fragment,{children:[Object.keys(Xe).length>0?(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`推荐模型`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_embedding_model&&Xe[m.knowledge_embedding_model]?m.knowledge_embedding_model:`__custom__`,disabled:!m.knowledge_enabled,onChange:e=>{e.target.value===`__custom__`?B({...m,knowledge_embedding_model:``}):B({...m,knowledge_embedding_model:e.target.value})},children:[Object.entries(Xe).map(([e,t])=>(0,R.jsx)(`option`,{value:e,children:t},e)),(0,R.jsx)(`option`,{value:`__custom__`,children:`自定义模型名...`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`从推荐列表中选择,或选"自定义模型名"手动输入。`})]}):null,(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_embedding_model`?`is-highlighted`:``}`,ref:V(`knowledge_embedding_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.knowledge_embedding_model,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_embedding_model:e.target.value}),placeholder:`BAAI/bge-small-zh-v1.5`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:m.knowledge_embedding_provider===`local_huggingface`?`HuggingFace 上的模型 ID,如 BAAI/bge-small-zh-v1.5。`:`ModelScope 上的模型 ID,如 BAAI/bge-small-zh-v1.5。`})]}),m.knowledge_embedding_provider===`local_huggingface`?(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`hf_endpoint`?`is-highlighted`:``}`,ref:V(`hf_endpoint`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`HuggingFace 镜像地址`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.hf_endpoint,disabled:!m.knowledge_enabled,onChange:e=>B({...m,hf_endpoint:e.target.value}),placeholder:`留空使用官方源,或填 https://hf-mirror.com`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`国内用户建议填写 https://hf-mirror.com 加速下载。`})]}):null,(0,R.jsxs)(`div`,{className:`settings-inline-actions`,style:{gridColumn:`1 / -1`},children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:Be||!m.knowledge_enabled,onClick:()=>void na(),children:Be?`下载中...`:`下载模型`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:He||Be||!m.knowledge_enabled,onClick:()=>void ra(),children:He?`验证中...`:`验证模型`}),Je?(0,R.jsx)(`span`,{className:`settings-status-pill success`,children:`已就绪`}):null]}),We?(0,R.jsx)(`div`,{className:`settings-inline-alert ${Je?`success`:We.includes(`失败`)?`warning`:`info`}`,children:(0,R.jsx)(`span`,{children:We})}):null,Ke?(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:10,readOnly:!0,value:Ke}):null]})]})]}),m.knowledge_embedding_provider===`siliconflow`?null:(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`03`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`运行依赖`}),(0,R.jsx)(`p`,{children:`知识库依赖(chromadb、sentence-transformers)需要到"运行环境"页面统一安装管理。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`div`,{className:`knowledge-deps-status-card ${yi?`status-ready`:`status-missing`}`,children:[(0,R.jsx)(`div`,{className:`knowledge-deps-status-icon`,children:yi?`✓`:`⚠`}),(0,R.jsxs)(`div`,{className:`knowledge-deps-status-content`,children:[(0,R.jsx)(`strong`,{className:`knowledge-deps-status-title`,children:yi?`依赖已就绪`:Ci?`依赖损坏`:`缺失 ${Ei.length} 个依赖`}),(0,R.jsx)(`p`,{className:`knowledge-deps-status-desc`,children:yi?`chromadb${g?.chromadbVersion?` ${g.chromadbVersion}`:``} 与 sentence-transformers${g?.sentenceTransformersVersion?` ${g.sentenceTransformersVersion}`:``} 已在当前运行环境可用。`:Ci?`部分依赖包已安装但无法正常导入,需要重新安装。`:`需要安装:${Ei.join(`、`)||Ti}。`})]})]}),(0,R.jsxs)(`div`,{className:`knowledge-deps-navigate`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,onClick:()=>{Ft(`runtime`),setTimeout(()=>{document.querySelector(`[data-focus-key="knowledge_runtime"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})},100)},children:`前往运行环境管理`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`在运行环境页面可以查看完整依赖树、安装/卸载单个依赖包、查看安装日志。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:m.knowledge_embedding_provider===`siliconflow`?`03`:`04`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`知识库 LLM`}),(0,R.jsx)(`p`,{children:`自动打标和知识库问答可以跟随主 LLM,也可以使用独立配置。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_llm_mode`?`is-highlighted`:``}`,ref:V(`knowledge_llm_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`LLM 来源`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_llm_mode||`same_as_main`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`same_as_main`,children:`跟随主 LLM`}),(0,R.jsx)(`option`,{value:`custom`,children:`使用独立配置`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`"跟随主 LLM" 会直接复用摘要 LLM 的 Base URL、API Key 与模型名。`})]}),ei?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_llm_enabled`?`is-highlighted`:``}`,ref:V(`knowledge_llm_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用知识库 LLM`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_llm_enabled?`true`:`false`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]})]}),m.knowledge_llm_enabled?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_provider`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`LLM 提供商`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_llm_provider||`openai-compatible`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI Compatible`}),(0,R.jsx)(`option`,{value:`openai`,children:`OpenAI`}),(0,R.jsx)(`option`,{value:`anthropic`,children:`Anthropic`}),(0,R.jsx)(`option`,{value:`custom`,children:`自建端点`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_base_url`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.knowledge_llm_base_url,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_base_url:e.target.value}),placeholder:`https://api.openai.com/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`知识库问答与自动打标 LLM API 的基础 URL 地址。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.knowledge_llm_api_key,disabled:!m.knowledge_enabled,onFocus:rJ,onChange:e=>B({...m,knowledge_llm_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`知识库 LLM 服务的 API 密钥。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.knowledge_llm_model,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_model:e.target.value}),placeholder:`gpt-4o-mini / claude-3-haiku`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`要用于知识库问答和自动打标的 LLM 模型名称。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:St||!m.knowledge_enabled,onClick:()=>void ca(),children:St?`测试中...`:`测试知识库 LLM`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用当前表单中的 Base URL、API Key 和模型名临时请求一次,并校验是否能返回合法 JSON,不会保存设置。`})]})]}):null]}):(0,R.jsxs)(`div`,{className:`settings-inline-alert ${ti?`success`:`warning`}`,children:[(0,R.jsx)(`strong`,{children:ti?`知识库当前跟随主 LLM`:`知识库当前跟随主 LLM,但主 LLM 还未补全`}),(0,R.jsx)(`span`,{children:ti?`自动打标和问答会直接复用主 LLM 配置。`:`请先启用主 LLM,并补全 API Key、Base URL 与模型名,或切换为独立配置。`})]})]})]})]})]}),Pt===`prompts`&&(0,R.jsxs)(`section`,{className:`settings-category-section settings-prompts-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`提示词`}),(0,R.jsx)(`p`,{children:`这里属于高级个性化区域。想改变知识笔记风格时再调整,日常使用保持默认即可。`})]}),(0,R.jsxs)(`div`,{className:`settings-prompt-scope-alert`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-scope-kicker`,children:`生效范围`}),(0,R.jsx)(`p`,{children:`首页选择的 Prompt 预设只影响摘要生成;知识笔记和图文笔记使用下方全局模板。恢复默认或修改模板后,需要点击左侧"保存设置"才会生效。`})]}),lr&&(0,R.jsxs)(`div`,{className:`settings-prompt-global-sticky`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-toolbar-title`,children:[`已展开 `,nr.size,` 项`]}),(0,R.jsx)(`button`,{className:`settings-prompt-inline-action`,type:`button`,onClick:e=>{e.preventDefault(),dr()},children:`收起全部`})]}),(0,R.jsxs)(`div`,{className:`settings-prompt-list`,children:[(0,R.jsxs)(`details`,{className:`settings-prompt-collapse`,ref:e=>{nn.current.summary=e},onToggle:e=>pr(`summary`,e),children:[(0,R.jsxs)(`summary`,{className:`settings-prompt-collapse-summary`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`摘要 Prompt`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`控制视频摘要的角色、结构和输出格式。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-chip accent`,children:`核心`}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_system_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要 System Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:5,value:m.summary_system_prompt||``,onChange:e=>B({...m,summary_system_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Hi(`system`),children:`恢复默认`}),On?.summary_system_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制视频摘要生成时的角色、风格和整体约束。`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_user_prompt_template`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要 User Template`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:14,value:m.summary_user_prompt_template||``,onChange:e=>B({...m,summary_user_prompt_template:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Hi(`template`),children:`恢复默认`}),On?.summary_user_prompt_template!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{transcript}`,`、`,`{segments_json}`,`。生成 JSON 包含 title/overview/bulletPoints/chapters/chapterGroups。`]})]})]})]})]}),(0,R.jsxs)(`div`,{className:`settings-prompt-collapse settings-focus-target ${En?` open`:``}`,ref:V(`prompt_presets_library`),children:[(0,R.jsxs)(`div`,{className:`settings-prompt-collapse-summary`,role:`button`,tabIndex:0,"aria-expanded":En,onClick:I,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),I())},children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`Prompt 预设库`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`管理首页摘要 Prompt 下拉框和自动推荐候选。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-chip`,children:[`内置 `,Kn]}),(0,R.jsxs)(`span`,{className:`settings-prompt-chip muted`,children:[`隐藏 `,qn]}),(0,R.jsxs)(`span`,{className:`settings-prompt-chip success`,children:[`新增 `,Jn]}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),En&&(0,R.jsxs)(`div`,{className:`settings-form-group`,style:{position:`relative`},children:[(0,R.jsxs)(`div`,{className:`settings-preset-section-note`,children:[(0,R.jsx)(`strong`,{children:`摘要预设`}),(0,R.jsx)(`span`,{children:`用于首页 Prompt 下拉框和自动推荐,只替换摘要 System Prompt / User Template。内置预设可查看或隐藏,新增预设可编辑或删除。`})]}),Qn.length?(0,R.jsxs)(`div`,{className:`settings-hidden-preset-list`,children:[(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`已隐藏内置预设`}),(0,R.jsx)(`div`,{className:`settings-hidden-preset-actions`,children:Qn.map(e=>(0,R.jsxs)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>er(e.id,!1),children:[`恢复 `,e.name]},e.id))})]}):null,fn?(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`加载中...`}):cn.length===0?(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`暂无预设`}):(0,R.jsx)(R.Fragment,{children:Yn.map(tr)}),gn&&(0,R.jsx)(`div`,{className:`settings-preset-card new`,children:(0,R.jsxs)(`div`,{className:`settings-preset-edit-body`,children:[(0,R.jsx)(`h4`,{children:`新建预设`}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`名称 *`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.name,onChange:e=>yn({...vn,name:e.target.value}),placeholder:`预设名称(用作 ID)`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`描述`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.description||``,onChange:e=>yn({...vn,description:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`分类`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.category||``,onChange:e=>yn({...vn,category:e.target.value}),placeholder:`例如: 教程、会议、娱乐`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动匹配关键词(逗号分隔)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.auto_match_keywords?.join(`、`)||``,onChange:e=>yn({...vn,auto_match_keywords:e.target.value.split(/[,,、]/).map(e=>e.trim()).filter(Boolean)}),placeholder:`例如: 教程、教学、入门`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`System Prompt *`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:4,value:vn.system_prompt,onChange:e=>yn({...vn,system_prompt:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`User Template *`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:10,value:vn.user_prompt_template,onChange:e=>yn({...vn,user_prompt_template:e.target.value})})]}),(0,R.jsxs)(`div`,{className:`settings-preset-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:bn,onClick:Un,children:bn?`创建中...`:`创建预设`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Bn,children:`取消`})]})]})}),Sn&&(0,R.jsx)(`p`,{className:`settings-input-caption`,style:{marginTop:8,color:Sn.includes(`失败`)?`var(--danger)`:`var(--success)`},children:Sn}),!gn&&!fn&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:zn,style:{marginTop:12},children:`+ 新建预设`})]})]}),(0,R.jsxs)(`details`,{className:`settings-prompt-collapse`,ref:e=>{nn.current.knowledge=e},onToggle:e=>pr(`knowledge`,e),children:[(0,R.jsxs)(`summary`,{className:`settings-prompt-collapse-summary`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`知识笔记 Prompt`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`控制知识笔记的整理风格、Markdown 结构和变量使用。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-chip`,children:`全局模板`}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_note_system_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`知识笔记 System Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:5,value:m.knowledge_note_system_prompt||``,onChange:e=>B({...m,knowledge_note_system_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ui(`system`),children:`恢复默认`}),On?.knowledge_note_system_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制知识笔记生成时的角色、风格和整体约束。`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_note_user_prompt_template`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`知识笔记 User Template`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:14,value:m.knowledge_note_user_prompt_template||``,onChange:e=>B({...m,knowledge_note_user_prompt_template:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ui(`template`),children:`恢复默认`}),On?.knowledge_note_user_prompt_template!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{transcript_excerpt}`,`、`,`{segments_excerpt}`,`、`,`{summary_json}`,`。`]})]})]}),(0,R.jsxs)(`div`,{className:`settings-guide-card`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`strong`,{children:`想调整知识笔记样式?`}),(0,R.jsx)(`span`,{children:`查看变量、默认结构和常见改法,避免破坏 JSON 输出格式。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Vt(!0),children:`打开教程`})]})]})]}),(0,R.jsxs)(`details`,{className:`settings-prompt-collapse`,ref:e=>{nn.current.visual=e},onToggle:e=>pr(`visual`,e),children:[(0,R.jsxs)(`summary`,{className:`settings-prompt-collapse-summary`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`图文笔记 Prompt`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`控制关键帧选择、画面理解和图文笔记整合。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-chip info`,children:`VLM`}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_note_system_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`图文笔记 System Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:5,value:m.visual_note_system_prompt||``,onChange:e=>B({...m,visual_note_system_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`system`),children:`恢复默认`}),On?.visual_note_system_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制理解型图文笔记如何把图片解析整合进正文。`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_frame_planning_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`捕获帧规划 Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:10,value:m.visual_frame_planning_prompt||``,onChange:e=>B({...m,visual_frame_planning_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`planning`),children:`恢复默认`}),On?.visual_frame_planning_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{mode}`,`、`,`{summary_json}`,`、`,`{knowledge_note_markdown}`,`、`,`{segments_excerpt}`,`、`,`{max_frames}`,`。`]})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_vlm_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`画面理解 Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:10,value:m.visual_vlm_prompt||``,onChange:e=>B({...m,visual_vlm_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`vlm`),children:`恢复默认`}),On?.visual_vlm_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{timestamp}`,`、`,`{context}`,`、`,`{timeline_hint}`,`、`,`{knowledge_note_markdown}`,`。`]})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_note_user_prompt_template`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`图文笔记 User Template`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:12,value:m.visual_note_user_prompt_template||``,onChange:e=>B({...m,visual_note_user_prompt_template:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`template`),children:`恢复默认`}),On?.visual_note_user_prompt_template!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{knowledge_note_markdown}`,`、`,`{visual_observations_json}`,`。`]})]})]})]})]})]})]}),Pt===`performance`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`性能调优`}),(0,R.jsx)(`p`,{children:`控制任务级并发与单任务内部分块并发,减少本地资源争抢和云端限流压力。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`task_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`任务并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.task_concurrency,onChange:e=>B({...m,task_concurrency:sJ(e.target.value,mi)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`影响下载、转写、摘要的整体链路吞吐;云 API 可能存在并发限流,建议按当前环境推荐值设置。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`mindmap_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`导图并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.mindmap_concurrency,onChange:e=>B({...m,mindmap_concurrency:sJ(e.target.value,1)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`影响摘要完成后的导图生成吞吐,不会占用摘要任务的并发槽位;建议保持 1。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要分块并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_concurrency,onChange:e=>B({...m,summary_chunk_concurrency:sJ(e.target.value,2)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`仅控制单个摘要任务内部同时请求的分块数量,不等同于任务并发数。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`当前建议`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:hi})]}),(0,R.jsxs)(`div`,{className:`settings-input-group settings-performance-tasklist-entry`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`当前任务队列`}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>qt(!0),children:`查看 tasklist`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用悬浮窗快速查看最近任务,避免占用主要设置区域。`})]})]})]})]}),Pt===`performance`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`资源策略`}),(0,R.jsx)(`p`,{children:`根据机器和任务规模调整 CUDA 版本、运行环境通道和缓存策略。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`cuda_variant`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`CUDA 变体`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.cuda_variant,onChange:e=>B({...m,cuda_variant:e.target.value}),children:[(0,R.jsx)(`option`,{value:`cu128`,children:`CUDA 12.8`}),(0,R.jsx)(`option`,{value:`cu126`,children:`CUDA 12.6`}),(0,R.jsx)(`option`,{value:`cu124`,children:`CUDA 12.4`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`PyTorch CUDA 版本`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`runtime_channel`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`运行环境通道`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.runtime_channel,onChange:e=>B({...m,runtime_channel:e.target.value}),children:[(0,R.jsx)(`option`,{value:`base`,children:`基础版`}),(0,R.jsx)(`option`,{value:`gpu-cu128`,children:`GPU CUDA12.8`}),(0,R.jsx)(`option`,{value:`gpu-cu126`,children:`GPU CUDA12.6`}),(0,R.jsx)(`option`,{value:`gpu-cu124`,children:`GPU CUDA12.4`})]})]})]})]}),Pt===`runtime`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`运行环境`}),(0,R.jsx)(`p`,{children:`环境检测信息、CUDA 配置和本地 ASR 安装。`})]}),(0,R.jsxs)(`div`,{className:`env-summary-grid settings-env-grid`,ref:V(`runtime_status`),children:[(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`推荐设备`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.recommendedDevice||`-`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`请求设备`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:Zn(m.device_preference)})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`生效设备`}),(0,R.jsx)(`strong`,{className:`metric-value ${(m.transcription_provider===`funasr`?Xn(m.funasr_device):Xn(m.whisper_device))===`cuda`?`text-success`:``}`,children:m.transcription_provider===`funasr`?Zn(m.funasr_device):Zn(m.whisper_device)})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`推荐模型`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.recommendedModel||`-`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`GPU 状态`}),(0,R.jsx)(`strong`,{className:`metric-value ${g?.cudaAvailable?`text-success`:``}`,children:g?.cudaAvailable?`已启用`:`未启用`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`GPU 名称`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.gpuName||`未检测到`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`Torch`}),(0,R.jsx)(`strong`,{className:`metric-value ${g?.torchInstalled?`text-success`:``}`,children:g?.torchInstalled?g?.torchVersion||`已安装`:`未安装`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`Python`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.pythonVersion||`-`})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`CUDA 目标版本`}),(0,R.jsxs)(`div`,{className:`cuda-insight-grid`,children:[(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`目标运行环境`}),(0,R.jsx)(`span`,{className:`setting-value`,children:Er})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`当前运行环境`}),(0,R.jsx)(`span`,{className:`setting-value`,children:g?.runtimeChannel||m.runtime_channel||`base`})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`运行环境状态`}),(0,R.jsx)(`span`,{className:`setting-value`,children:g?.runtimeReady?`已就绪`:g?.runtimeError?`异常`:`检测中...`})]})]}),(0,R.jsx)(`span`,{className:`input-label`,children:`CUDA 目标版本`}),(0,R.jsxs)(`div`,{className:`settings-actions cuda-button-row`,children:[(0,R.jsxs)(`select`,{className:`select-field cuda-select-field`,value:m.cuda_variant,disabled:k,onChange:e=>B({...m,cuda_variant:e.target.value}),children:[(0,R.jsx)(`option`,{value:`cu128`,children:`CUDA 12.8`}),(0,R.jsx)(`option`,{value:`cu126`,children:`CUDA 12.6`}),(0,R.jsx)(`option`,{value:`cu124`,children:`CUDA 12.4`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:k,onClick:async()=>{try{E(`正在重新检测环境...`),_(await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0})),E(`环境检测完成`),i()}catch(e){E(e instanceof Error?e.message:`环境检测失败`)}},children:`重新检测`}),(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:k,onClick:async()=>{let e=`cuda-${Date.now()}`,t=null;try{A(!0),E(`正在安装 CUDA 支持...`),O(``),M(0),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&O(n.log),typeof n.progress==`number`&&M(n.progress),n.done&&t&&(clearInterval(t),t=null)}catch{}},1500);let n=await L.installCuda({cuda_variant:m.cuda_variant,installSessionId:e});t&&=(clearInterval(t),null),M(100);try{let t=await L.getInstallLog(e);t.log&&O(t.log)}catch{}let r=n.runtimeChannel||m.runtime_channel;A(!1),E(n.restartRequired?`CUDA 安装完成,请重启应用后切换到新的 GPU 运行环境`:`CUDA 安装完成`),h({...m,runtime_channel:r,cuda_variant:n.cudaVariant||m.cuda_variant}),y(!1),_(await L.getEnvironment({runtimeChannel:r,refresh:!0})),i()}catch(e){t&&=(clearInterval(t),null),A(!1),E(e instanceof Error?e.message:`CUDA 安装失败`)}},children:k?`安装中...`:`安装 CUDA 支持`})]}),k||T||D?(0,R.jsx)(`div`,{className:`settings-form-group`,children:(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`CUDA 安装输出`}),k&&j>0?(0,R.jsx)(`div`,{className:`progress-bar-simple`,style:{marginBottom:8},children:(0,R.jsx)(`div`,{className:`progress-fill-simple`,style:{width:`${j}%`}})}):null,(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:12,readOnly:!0,value:D||(k?`安装中...`:T)})]})}):null]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`运行环境更新检查`}),(0,R.jsxs)(`div`,{className:`settings-runtime-toolbar`,children:[(0,R.jsxs)(`span`,{className:`settings-inline-alert ${Ai.length>0?`warning`:`success`}`,children:[(0,R.jsx)(`strong`,{children:Ai.length>0?`有运行环境需要同步`:`运行环境基础版本一致`}),(0,R.jsx)(`span`,{children:Ai.length>0?`${Ai.map(e=>e.runtimeChannel).join(`、`)} 需要同步基础文件;同步会保留 CUDA / ASR / 知识库扩展包。`:`当前基础版本 ${et?.baseAppVersion||`-`},每 30 分钟自动检查一次。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:it,onClick:()=>void gr(),children:it?`检查中...`:`检查所有 runtime`}),Ai.length>0&&(0,R.jsx)(`button`,{className:`primary-button compact`,type:`button`,disabled:ot||it,onClick:()=>void _r(),children:ot?`同步中...`:`同步需要更新的 runtime`})]}),nt?(0,R.jsx)(`p`,{className:`settings-input-caption runtime-status-message`,children:nt}):null,(0,R.jsx)(`div`,{className:`runtime-channel-list`,role:`list`,children:(et?.channels||[]).map(e=>(0,R.jsxs)(`div`,{className:`runtime-channel-row`,role:`listitem`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`strong`,{children:e.runtimeChannel}),(0,R.jsx)(`span`,{children:e.ready?`已就绪`:e.exists?`缺少 Python`:`未创建`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{children:e.appVersion||`-`}),(0,R.jsx)(`span`,{children:e.needsUpdate?`需同步`:e.exists?`最新`:`按需创建`})]})]},e.runtimeChannel))}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`已启用国内镜像回退:`,ji,`。安装失败时会自动从官方源切换到国内镜像继续尝试。`]})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-list`,children:[(0,R.jsxs)(cJ,{title:`本地 ASR 运行环境`,status:vi?`已安装`:`未安装`,tone:vi?`installed`:`missing`,summary:vi?`faster-whisper ${g?.localAsrVersion||`已就绪`}`:`安装后可切换到本地 Whisper 转写`,open:An,onToggle:()=>jn(!An),focusKey:`local_asr_runtime`,highlighted:Rt===`local_asr_runtime`,sectionRef:V(`local_asr_runtime`),children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-intro`,children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-copy`,children:[(0,R.jsx)(`strong`,{children:vi?`本地 Whisper 已可用`:`安装到当前 runtime`}),(0,R.jsx)(`span`,{children:vi?`当前运行环境可直接使用本地语音识别;重新安装会保留同一运行环境通道并刷新依赖。`:`正式安装包默认不包含本地 ASR,安装完成后会自动切换到本地模式。`})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:ge,onClick:()=>void Zi(),children:ge?`安装中...`:vi?`重新安装本地 ASR`:`安装本地 ASR`}),fe?(0,R.jsx)(`span`,{className:`helper-chip runtime-operation-chip ${fe.includes(`失败`)?`status-error`:fe.includes(`安装`)||fe.includes(`已`)?`status-success`:`status-info`}`,children:fe}):null]})]}),(0,R.jsx)(Vq,{title:`本地 ASR 依赖`,items:Wq(g,`local`),runtimeChannel:m.runtime_channel,installKind:`local`,onStatusChange:ta}),me?(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title`,children:`安装输出`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:me})]}):null]}),(0,R.jsxs)(cJ,{title:`FunASR 运行环境`,status:ui?`已安装`:`未安装`,tone:ui?`installed`:`missing`,summary:ui?`funasr ${g?.funasrVersion||`已就绪`}`:`中文转写增强,包含 PyTorch 依赖`,open:Mn,onToggle:()=>Nn(!Mn),focusKey:`funasr_runtime`,highlighted:Rt===`funasr_runtime`,sectionRef:V(`funasr_runtime`),children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-intro`,children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-copy`,children:[(0,R.jsx)(`strong`,{children:ui?`FunASR 已可用`:`安装中文 ASR 增强包`}),(0,R.jsx)(`span`,{children:ui?`当前运行环境已经通过 FunASR 检测;重新安装会自动修复 torch、torchvision、torchaudio 等子依赖。`:`FunASR 是阿里开源语音识别引擎,依赖包含 PyTorch,安装体积较大,请耐心等待。`})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:Se,onClick:()=>void Qi(),children:Se?`安装中...`:ui?`重新安装 FunASR`:`安装 FunASR`}),ve?(0,R.jsx)(`span`,{className:`helper-chip runtime-operation-chip ${ve.includes(`失败`)?`status-error`:ve.includes(`已安装`)||ve.includes(`成功`)?`status-success`:`status-info`}`,children:ve}):null]})]}),(0,R.jsx)(Vq,{title:`FunASR 依赖`,items:Wq(g,`funasr`),runtimeChannel:m.runtime_channel,installKind:`funasr`,onStatusChange:ta}),be?(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title`,children:`安装输出`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:be})]}):null]}),(0,R.jsxs)(cJ,{title:`知识库运行环境`,status:Di,tone:Oi,summary:ki,open:Pn,onToggle:()=>Fn(!Pn),focusKey:`knowledge_runtime`,highlighted:Rt===`knowledge_runtime`,sectionRef:V(`knowledge_runtime`),children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-intro`,children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-copy`,children:[(0,R.jsx)(`strong`,{children:yi?`知识库依赖已就绪`:Ci?`依赖需要修复`:`安装知识库依赖`}),(0,R.jsx)(`span`,{children:Rr?`当前 provider: siliconflow。本区域只负责本地知识库索引存储依赖,在线向量模型请在「知识库与问答」里测试。`:`当前 provider: ${m.knowledge_embedding_provider||`local_huggingface`}。本区域负责知识库索引存储和本地向量模型所需的 Python 依赖。`})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:Ie,onClick:()=>void $i(),children:Ie?`安装中...`:yi||Ci?`重新安装知识库依赖`:`安装知识库依赖`}),Me?(0,R.jsx)(`span`,{className:`helper-chip runtime-operation-chip ${Me.includes(`成功`)||Me.includes(`就绪`)?`status-success`:Me.includes(`失败`)?`status-error`:`status-info`}`,children:Me}):null]})]}),Re&&(0,R.jsx)(`div`,{className:`runtime-subsection-group`,ref:V(`knowledge_dependencies`),children:(0,R.jsx)(Vq,{title:`知识库依赖`,items:Uq(Re,g),runtimeChannel:m.runtime_channel,installKind:`knowledge`,provider:m.knowledge_embedding_provider||`local_huggingface`,onStatusChange:ta})}),Pe?(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title`,children:`安装输出`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:Pe})]}):null,(g?.chromadbError||g?.sentenceTransformersError||g?.modelscopeError)&&(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsxs)(`div`,{className:`settings-inline-alert warning runtime-inline-alert`,children:[(0,R.jsx)(`strong`,{children:`依赖损坏,需要重新安装`}),(0,R.jsx)(`span`,{children:`部分依赖包已安装但无法正常导入,请点击上方“重新安装知识库依赖”自动修复。`})]}),(0,R.jsx)(`span`,{className:`runtime-block-title runtime-block-title-warning`,children:`包导入错误`}),(0,R.jsxs)(`div`,{className:`runtime-error-stack`,children:[g.chromadbError&&(0,R.jsxs)(`div`,{className:`runtime-error-item`,children:[(0,R.jsx)(`span`,{className:`runtime-error-label`,children:`chromadb`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea`,rows:4,readOnly:!0,value:g.chromadbError})]}),g.sentenceTransformersError&&(0,R.jsxs)(`div`,{className:`runtime-error-item`,children:[(0,R.jsx)(`span`,{className:`runtime-error-label`,children:`sentence-transformers`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea`,rows:4,readOnly:!0,value:g.sentenceTransformersError})]}),g.modelscopeError&&(0,R.jsxs)(`div`,{className:`runtime-error-item`,children:[(0,R.jsx)(`span`,{className:`runtime-error-label`,children:`modelscope`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea`,rows:4,readOnly:!0,value:g.modelscopeError})]})]})]}),g?.knowledgeDependenciesError&&!g?.chromadbError&&!g?.sentenceTransformersError&&!g?.modelscopeError&&(0,R.jsxs)(`div`,{className:`runtime-log-block is-error`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title runtime-block-title-danger`,children:`知识库依赖错误`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea is-error`,rows:6,readOnly:!0,value:g.knowledgeDependenciesError})]})]})]}),g?.runtimeError?(0,R.jsx)(`div`,{className:`settings-form-group`,children:(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`运行环境错误详情`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:g.runtimeError})]})}):null]}),Pt===`logs`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`日志与控制`}),(0,R.jsx)(`p`,{children:`查看服务日志、管理后端进程、配置桌面行为与监听参数。`})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`服务状态`}),(0,R.jsxs)(`div`,{className:`control-status-row`,ref:V(`service_logs`),children:[(0,R.jsx)(`span`,{className:`helper-chip ${wr?`status-success`:Sr?`status-running`:`status-failed`}`,children:wr?`服务在线`:Sr?`启动中...`:`服务离线`}),(0,R.jsx)(`span`,{className:`helper-chip ${Sr?Cr?`status-success`:`status-running`:`status-pending`}`,children:Sr?Cr?`内置后端运行中`:`内置后端启动中`:`内置后端未运行`}),t.backend?.pid?(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`PID `,t.backend.pid]}):null]}),(0,R.jsxs)(`div`,{className:`cuda-insight-grid`,children:[(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`服务名`}),(0,R.jsx)(`span`,{className:`setting-value`,children:e.systemInfo?.application?.name||`-`})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`版本`}),(0,R.jsx)(`span`,{className:`setting-value`,children:e.systemInfo?.application?.version||`-`})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`日志文件`}),(0,R.jsx)(`span`,{className:`setting-value`,style:{fontSize:`0.82rem`,wordBreak:`break-all`,overflowWrap:`anywhere`},children:Tr})]})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`服务管理`}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`监听地址`}),(0,R.jsx)(`input`,{className:`settings-input-field`,ref:V(`host`),value:m.host,onChange:e=>B({...m,host:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`服务绑定的 IP 地址,默认 127.0.0.1。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`监听端口`}),(0,R.jsx)(`input`,{className:`settings-input-field`,ref:V(`port`),type:`number`,value:m.port,onChange:e=>B({...m,port:parseInt(e.target.value)||3838})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`服务端口号,默认 3838。只有端口冲突或外部接入时再调整。`})]})]}),(0,R.jsxs)(`div`,{className:`desktop-actions`,children:[(0,R.jsx)(`button`,{className:Sr?`secondary-button danger-button`:`primary-button`,type:`button`,onClick:async()=>{Sr?(await window.desktop?.backend.stop(),pt(`内置后端已停止`)):(await window.desktop?.backend.start(),pt(`已请求启动内置后端`)),i(),await mr()},children:Sr?`停止内置后端`:`启动内置后端`}),Sr&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:async()=>{pt(`正在重启内置后端...`),await window.desktop?.backend.stop(),await new Promise(e=>setTimeout(e,1500)),await window.desktop?.backend.start(),pt(`内置后端已重启`),i(),await mr()},children:`重启后端`}),(0,R.jsx)(`button`,{className:`secondary-button danger-button`,type:`button`,disabled:!wr,onClick:async()=>{await L.shutdownService(),pt(`已向服务发送关闭请求`),i(),await mr()},children:`强制关闭服务`})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`桌面偏好`}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`开机自启动`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`系统启动时自动运行 BiliSum。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:te,onChange:async e=>{let t=e.target.checked,n=await window.desktop?.app?.setAutoLaunch(t);typeof n==`boolean`&&(P(n),n!==t&&w(`开机自启动${t?`开启`:`关闭`}失败,请检查系统权限`))}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`开机静默启动`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`开机自启时隐藏窗口,仅显示托盘图标。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:F,disabled:!te,onChange:async e=>{let t=e.target.checked;ne(t),await window.desktop?.preferences?.setSilentStart(t)}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`崩溃自动重启`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`后端服务非预期退出时自动拉起。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:re,onChange:async e=>{let t=e.target.checked;ie(t),await window.desktop?.preferences?.setCrashAutoRestart(t)}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`开发者模式`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`开启后显示后台日志和浏览器开发者工具,便于调试问题。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:ae,onChange:async e=>{let t=e.target.checked;oe(t),await window.desktop?.preferences?.setDeveloperMode(t)}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`关闭窗口行为`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,style:{maxWidth:200},value:N,onChange:async e=>{let t=e.target.value;ee(t),await window.desktop?.preferences?.setCloseBehavior(t)},children:[(0,R.jsx)(`option`,{value:`tray`,children:`最小化到托盘`}),(0,R.jsx)(`option`,{value:`exit`,children:`直接退出应用`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`点击窗口关闭按钮时的行为。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-reset-row`,children:[(0,R.jsxs)(`div`,{className:`settings-reset-row-copy`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`首页引导`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`重新显示首次进入首页的功能指引。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>{window.localStorage.removeItem(`bilisum.homeTourSeen`),window.localStorage.removeItem(`bilisum.summaryPreferenceHintSeen`),w(`已清空首页引导记录。`)},children:`重新显示`})]}),(0,R.jsxs)(`div`,{className:`settings-reset-row`,children:[(0,R.jsxs)(`div`,{className:`settings-reset-row-copy`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`配置引导`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`重新打开首次配置引导助手。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>{p(),w(`已打开配置引导。`)},children:`打开配置引导`})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`日志`}),(0,R.jsx)(`div`,{className:`settings-input-group`,style:{marginBottom:12},children:(0,R.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:12,flexWrap:`wrap`},children:[(0,R.jsx)(`div`,{style:{display:`flex`,gap:6},children:[`all`,`ERROR`,`WARNING`,`INFO`].map(e=>(0,R.jsx)(`button`,{type:`button`,className:`filter-pill${le===e?` active`:``}`,onClick:()=>ue(e),children:e===`all`?`全部`:e},e))}),(0,R.jsx)(`div`,{style:{flex:1}}),(0,R.jsxs)(`div`,{className:`settings-toggle-row`,style:{gap:8},children:[(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`自动刷新`}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:se,onChange:e=>ce(e.target.checked)}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})]})}),(0,R.jsx)(`textarea`,{ref:de,className:`textarea-field log-viewer`,rows:22,readOnly:!0,value:hr||`暂无日志`}),(0,R.jsxs)(`div`,{className:`desktop-actions`,style:{marginTop:12},children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>void mr(),children:`刷新日志`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:async()=>{await window.desktop?.shell.openPath(Tr)},children:`打开日志文件`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:async()=>{let e=await window.desktop?.logs?.exportLog?.();e&&pt(`日志已导出到 ${e}`)},children:`导出日志`}),(0,R.jsx)(`button`,{className:`secondary-button danger-button`,type:`button`,onClick:async()=>{await window.desktop?.logs?.clearLog?.(),await mr(),pt(`日志已清空`)},children:`清空日志`})]})]})]}),Pt===`updates`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`桌面应用更新`}),(0,R.jsx)(`p`,{children:c?`检查新版本并管理安装。`:`查看最新版本信息与更新日志。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-module`,ref:V(`app_updates`),children:[(0,R.jsxs)(`div`,{className:`settings-update-overview`,children:[(0,R.jsxs)(`div`,{className:`settings-update-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`Update`}),(0,R.jsx)(`h3`,{children:c?`手动检查桌面端更新`:`手动检查最新版本`}),(0,R.jsx)(`p`,{children:ci})]}),(0,R.jsxs)(`div`,{className:`settings-update-badges`,children:[(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`当前版本 v`,ri]}),(0,R.jsxs)(`span`,{className:`helper-chip status-${si}`,children:[`状态:`,oi]}),o.version?(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`最新版本 v`,o.version]}):null,o.releaseDate?(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`发布时间 `,sr(o.releaseDate)]}):null]})]}),(0,R.jsxs)(`div`,{className:`settings-update-grid`,children:[(0,R.jsxs)(`div`,{className:`settings-update-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`当前安装版本`}),(0,R.jsxs)(`strong`,{children:[`v`,ri]}),(0,R.jsx)(`p`,{children:c?`检查、下载和安装更新。`:`当前环境仅支持检查最新版本。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-panel ${o.status===`available`||o.status===`downloaded`?`is-highlight`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`检查结果`}),(0,R.jsx)(`strong`,{children:ai?`当前环境不可更新`:o.status===`available`||o.status===`downloaded`?`发现 v${o.version||`-`}`:o.status===`not-available`?`已是最新版本`:o.status===`error`?`检查失败`:o.status===`checking`?`正在检查`:o.status===`downloading`?`下载中 ${Math.round(o.downloadProgress)}%`:o.status===`installing`?`正在安装`:`等待检查`}),(0,R.jsx)(`p`,{children:!c&&o.status===`available`?`已检测到 v${o.version||`-`},请使用桌面安装包完成更新。`:!c&&o.status===`not-available`?`当前环境可查看最新版本信息,但不支持自动下载或安装。`:o.status===`available`||o.status===`downloaded`?`当前 v${ri},最新 v${o.version||`-`}`:o.status===`error`?o.errorMessage||`更新检查失败,请重试。`:ci})]})]}),(0,R.jsxs)(`div`,{className:`settings-update-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:!s||li,onClick:async()=>{try{if(!s)return;if(c&&o.status===`available`){await u();return}if(c&&o.status===`downloaded`){await d();return}await l()}catch{}},children:s?c?o.status===`checking`?`检查中...`:o.status===`downloading`?`下载中... ${Math.round(o.downloadProgress)}%`:o.status===`installing`?`安装中...`:o.status===`available`?`下载并重启安装`:o.status===`downloaded`?`立即重启安装`:o.status===`error`?`重试检查`:`检查更新`:o.status===`checking`?`检查中...`:`检查更新`:`当前环境无法检查更新`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:!s,onClick:f,children:`查看更新详情`})]}),o.status===`available`||o.status===`downloaded`?(0,R.jsxs)(`div`,{className:`settings-update-next-step`,children:[(0,R.jsx)(`strong`,{children:`下一步`}),(0,R.jsx)(`span`,{children:c?o.status===`available`?`已检测到新版本,继续后会下载更新并自动重启安装。`:`更新已下载完成,可以立即重启应用完成安装。`:`当前环境仅支持查看最新版本信息,请前往桌面安装包完成更新。`})]}):null]})]}),(0,R.jsx)(`button`,{className:`settings-collapse-all-fab`,type:`button`,"aria-label":`回到顶部`,onClick:e=>{e.preventDefault(),fr()},title:`回到顶部`,children:(0,R.jsxs)(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,R.jsx)(`polyline`,{points:`18 15 12 9 6 15`}),(0,R.jsx)(`line`,{x1:`12`,y1:`9`,x2:`12`,y2:`21`}),(0,R.jsx)(`line`,{x1:`6`,y1:`3`,x2:`18`,y2:`3`})]})})]})}),Ht?(0,R.jsx)(`div`,{className:`update-dialog-overlay`,role:`presentation`,onClick:ua,children:(0,R.jsxs)(`section`,{className:`update-dialog generation-model-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`generation-model-dialog-title`,onClick:e=>e.stopPropagation(),children:[(0,R.jsxs)(`header`,{className:`update-dialog-header`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-model-kicker`,children:`模型接入`}),(0,R.jsx)(`h2`,{id:`generation-model-dialog-title`,children:Ht===`main`?`主摘要模型`:`视觉理解模型`})]}),(0,R.jsx)(`button`,{className:`close-button`,type:`button`,"aria-label":`关闭模型配置`,onClick:ua,children:`×`})]}),(0,R.jsx)(`div`,{className:`update-dialog-body generation-model-dialog-body`,children:Ht===`main`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`LLM 提供商`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.llm_provider,onChange:e=>B({...m,llm_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI Compatible`}),(0,R.jsx)(`option`,{value:`openai`,children:`OpenAI`}),(0,R.jsx)(`option`,{value:`anthropic`,children:`Anthropic`}),(0,R.jsx)(`option`,{value:`custom`,children:`自建端点`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`llm_base_url`?`is-highlighted`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.llm_base_url,onChange:e=>B({...m,llm_base_url:e.target.value}),placeholder:`https://api.openai.com/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`主摘要 LLM API 的基础 URL 地址。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`llm_api_key`?`is-highlighted`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.llm_api_key,onFocus:rJ,onChange:e=>B({...m,llm_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`已保存的密钥会用 ****** 显示,直接输入新值即可替换。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`llm_model`?`is-highlighted`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.llm_model,onChange:e=>B({...m,llm_model:e.target.value}),placeholder:`gpt-4o-mini / claude-3-haiku`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-alert ${Vr?`success`:`warning`}`,children:[(0,R.jsx)(`strong`,{children:Vr?`主摘要模型配置完整`:`主摘要模型仍需补全`}),(0,R.jsx)(`span`,{children:Vr?`可以保存后用于摘要、导图和默认视觉模型。`:`启用 LLM 摘要时,需要 Base URL、API Key 与模型名称都有效。`})]})]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`settings-inline-alert info`,children:[(0,R.jsx)(`strong`,{children:`默认跟随主 LLM`}),(0,R.jsx)(`span`,{children:`视觉字段留空时,会复用主摘要模型的 Base URL、API Key 和模型名称;只有需要单独 VLM 时再填写。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉模型提供商`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_vlm_provider||`openai-compatible`,onChange:e=>B({...m,visual_vlm_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI Compatible`}),(0,R.jsx)(`option`,{value:`openai`,children:`OpenAI`}),(0,R.jsx)(`option`,{value:`anthropic`,children:`Anthropic`}),(0,R.jsx)(`option`,{value:`custom`,children:`自建端点`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉 API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.visual_evidence_base_url,onChange:e=>B({...m,visual_evidence_base_url:e.target.value}),placeholder:`留空则跟随主 LLM Base URL`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.visual_evidence_model,onChange:e=>B({...m,visual_evidence_model:e.target.value}),placeholder:`留空则跟随主 LLM 模型`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉 API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.visual_evidence_api_key,onFocus:rJ,onChange:e=>B({...m,visual_evidence_api_key:e.target.value}),placeholder:`留空则跟随主 LLM API Key`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-alert ${Hr?`success`:`warning`}`,children:[(0,R.jsx)(`strong`,{children:Hr?`视觉模型配置完整`:`视觉模型会等待有效模型配置`}),(0,R.jsx)(`span`,{children:Hr?`当前有效配置可用于理解型图文笔记。`:`请补全独立视觉配置,或确保主摘要模型已完整配置。`})]})]})}),(0,R.jsxs)(`footer`,{className:`update-dialog-footer`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:ua,children:`关闭`}),(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:St,onClick:()=>void(Ht===`main`?sa():la()),children:St?`测试中...`:Ht===`main`?`测试主模型`:`测试视觉模型`})]})]})}):null,Bt?(0,R.jsx)(`div`,{className:`update-dialog-overlay`,role:`presentation`,onClick:()=>Vt(!1),children:(0,R.jsxs)(`section`,{className:`update-dialog knowledge-prompt-guide-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`knowledge-prompt-guide-title`,onClick:e=>e.stopPropagation(),children:[(0,R.jsxs)(`header`,{className:`update-dialog-header`,children:[(0,R.jsx)(`h2`,{id:`knowledge-prompt-guide-title`,children:`知识笔记提示词教程`}),(0,R.jsx)(`button`,{className:`close-button`,type:`button`,"aria-label":`关闭教程`,onClick:()=>Vt(!1),children:`×`})]}),(0,R.jsxs)(`div`,{className:`update-dialog-body knowledge-prompt-guide-body`,children:[(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`两个输入框分别控制什么`}),(0,R.jsx)(`p`,{children:`System Prompt 负责定义角色、底线和总体风格,例如"严谨的中文知识编辑""不得编造""只输出 JSON"。 User Template 负责规定笔记结构、可用素材和输出格式,是调整笔记样式的主要位置。`})]}),(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`可用变量`}),(0,R.jsxs)(`div`,{className:`knowledge-prompt-guide-grid`,children:[(0,R.jsx)(`span`,{children:`{title}`}),(0,R.jsx)(`p`,{children:`视频标题,适合用于生成笔记标题或判断主题。`}),(0,R.jsx)(`span`,{children:`{summary_json}`}),(0,R.jsx)(`p`,{children:`前一步结构化摘要,包含要点、章节、结论等信息。可以保留,也可以在模板里弱化它的权重。`}),(0,R.jsx)(`span`,{children:`{transcript_excerpt}`}),(0,R.jsx)(`p`,{children:`转写节选,适合补充细节和原文语境。`}),(0,R.jsx)(`span`,{children:`{segments_excerpt}`}),(0,R.jsx)(`p`,{children:`带时间或分段的信息,适合让笔记按章节展开。`})]})]}),(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`默认笔记格式`}),(0,R.jsx)(`p`,{children:`默认模板倾向生成一篇长阅读型 Markdown 笔记,通常包含:`}),(0,R.jsxs)(`ul`,{children:[(0,R.jsx)(`li`,{children:`核心结论:先给出视频最重要的观点。`}),(0,R.jsx)(`li`,{children:`关键概念:整理定义、条件、术语和背景。`}),(0,R.jsx)(`li`,{children:`章节展开:按内容推进顺序补全上下文。`}),(0,R.jsx)(`li`,{children:`易错点或限制:保留限制、争议、例外和注意事项。`})]})]}),(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`怎么修改笔记样式`}),(0,R.jsx)(`p`,{children:`想改格式时,优先改 User Template 里的"写作要求"或"目标结构"。例如:`}),(0,R.jsx)(`pre`,{children:`请把 knowledgeNoteMarkdown 写成以下结构:
342
+ `);(0,S.useEffect)(()=>{let e=de.current;e&&requestAnimationFrame(()=>{e.scrollTop=e.scrollHeight})},[hr]);async function gr(e={}){try{at(!0),e.silent||rt(`正在检查所有运行环境...`);let t=await L.getRuntimeStatus();if(tt(t),m?.runtime_channel){let e=await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});_(e),a(m,e)}let n=t.channels.filter(e=>e.needsUpdate).length;e.silent||rt(n>0?`${n} 个运行环境需要同步基础版本。`:`所有已安装运行环境均为最新基础版本。`)}catch(t){e.silent||rt(t instanceof Error?t.message:`运行环境检查失败`)}finally{at(!1)}}async function _r(){if(!(!m||ot))try{st(!0),rt(`正在同步需要更新的运行环境...`);let e=await L.syncRuntime();e.runtimeStatus?tt(e.runtimeStatus):await gr({silent:!0});let t=e.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});_(t),a(m,t);let n=e.channels?.filter(e=>e.synced).length??0;rt(n>0?`已同步 ${n} 个运行环境,保留 CUDA / ASR / 知识库扩展包。`:`运行环境已检查,无需同步。`),i()}catch(e){rt(e instanceof Error?e.message:`运行环境同步失败`)}finally{st(!1)}}let vr=(0,S.useCallback)(async()=>{if(!m||!window.desktop?.fileManager){Nt(`当前环境不支持文件管理。`);return}try{kt(!0),Nt(``);let t;if(e.serviceOnline)try{t=(await L.listTasks()).map(e=>e.task_id)}catch{t=void 0}Dt(await window.desktop.fileManager.getStorageOverview({taskIds:t})),t||Nt(`服务离线:已展示本地占用情况,清理操作需要在服务在线时确认引用关系。`)}catch(e){Nt(e instanceof Error?e.message:`读取文件占用失败`)}finally{kt(!1)}},[m,e.serviceOnline]);async function yr(e){!m||!window.desktop?.fileManager||await window.desktop.fileManager.openDirectory(e)}async function br(){if(!(!m||!window.desktop?.fileManager||!wr))try{jt(!0),Nt(``);let e=(await L.listTasks()).map(e=>e.task_id),t=await window.desktop.fileManager.getStorageOverview({taskIds:e}),n=t.cleanup.orphanTaskCount+t.cleanup.cacheCandidateCount,r=t.cleanup.orphanTaskBytes+t.cleanup.cacheCandidateBytes;if(n<=0){Dt(t),Nt(`当前没有可安全清理的缓存或孤儿文件。`);return}if(!window.confirm(`将删除 ${n} 项可回收内容,预计释放 ${aJ(r)}。\n\n包含:${t.cleanup.orphanTaskCount} 个孤儿任务目录、${t.cleanup.cacheCandidateCount} 个缓存项。\n此操作不会删除仍被引用的任务结果。`)){Dt(t),Nt(`已取消清理。`);return}let i=await window.desktop.fileManager.cleanupOrphans({taskIds:e});await vr(),Nt(`已清理 ${i.deletedCount} 项内容,释放约 ${aJ(i.reclaimedBytes)}。`)}catch(e){Nt(e instanceof Error?e.message:`清理文件失败`)}finally{jt(!1)}}async function xr(){try{Yt(!0),Zt(``),$t((await L.listTasks()).slice(0,Xq))}catch(e){Zt(e instanceof Error?e.message:`读取任务列表失败`)}finally{Yt(!1)}}let Sr=!!t.backend?.running,Cr=!!t.backend?.ready,wr=e.serviceOnline,Tr=ut||e.systemInfo?.service?.log_file||t.logPath||`-`,Er=`gpu-${m?.cuda_variant||`cu128`}`,Dr=Gq.find(e=>e.id===Pt)||Gq[0],Or=Gq.filter(e=>e.group===`workflow`),kr=Gq.filter(e=>e.group===`system`),Ar=Wt.trim().toLowerCase(),jr=Ar.split(/\s+/).filter(Boolean),Mr=Ar?iJ.map(e=>{let t=Gq.find(t=>t.id===e.category),n=[e.title,e.description,t?.label||``,t?.description||``,...e.keywords].join(` `).toLowerCase();return jr.every(e=>n.includes(e))?{...e,categoryLabel:t?.label||e.category}:null}).filter(e=>!!e).slice(0,8):[],Pr=tJ(m?.llm_api_key,m?.llm_api_key_configured),Fr=tJ(m?.visual_evidence_api_key,m?.visual_evidence_api_key_configured)||Pr,Ir=tJ(m?.knowledge_llm_api_key,m?.knowledge_llm_api_key_configured),Lr=tJ(m?.siliconflow_embedding_api_key,m?.siliconflow_embedding_api_key_configured),Rr=String(m?.knowledge_embedding_provider||`local_huggingface`).trim().toLowerCase()===`siliconflow`,zr=!!m?.llm_enabled,Br=!!m?.visual_multimodal_enabled,Vr=!!(m?.llm_enabled&&Pr&&String(m?.llm_base_url||``).trim()&&String(m?.llm_model||``).trim()),Hr=!!(m?.visual_multimodal_enabled&&Fr&&String(m?.visual_evidence_base_url||m?.llm_base_url||``).trim()&&String(m?.visual_evidence_model||m?.llm_model||``).trim()),Wr=wt.main,Gr=wt.visual,Kr=Wr.status===`available`?`可用`:Wr.status===`unavailable`?`不可用`:Wr.status===`checking`?`检查中`:Vr?`可用`:zr?`待配置`:`关闭`,Jr=Wr.status===`available`||Wr.status===`unknown`&&Vr?`success`:Wr.status===`unavailable`?`danger`:Wr.status===`checking`||zr?`warning`:``,Yr=zr?Wr.status===`unavailable`?`不可用`:Vr?`已配置`:`待补全`:`未启用`,Xr=Gr.status===`available`?`可用`:Gr.status===`unavailable`?`不可用`:Gr.status===`checking`?`检查中`:Hr?`可用`:Br?`待确认`:`关闭`,Zr=Gr.status===`available`||Gr.status===`unknown`&&Hr?`success`:Gr.status===`unavailable`?`danger`:Gr.status===`checking`||Br?`warning`:``,Qr=Br?Gr.status===`unavailable`?`不可用`:Hr?`已配置`:`跟随或待补全`:`未启用`,$r=(()=>{let e=m?.visual_note_mode||`text`;return e===`vlm_integrated`?`multimodal`:e===`frame_insert`?`visual`:`text`})(),ei=String(m?.knowledge_llm_mode||`same_as_main`).trim().toLowerCase()===`custom`,ti=ei?!!(m?.knowledge_llm_enabled&&Ir&&String(m?.knowledge_llm_base_url||``).trim()&&String(m?.knowledge_llm_model||``).trim()):!!(m?.llm_enabled&&Pr&&String(m?.llm_base_url||``).trim()&&String(m?.llm_model||``).trim()),ni=!!m?.auto_generate_mindmap,ri=t.version||e.systemInfo?.application?.version||`-`,ii=m?.transcription_provider===`local`?!!g?.localAsrAvailable:m?.transcription_provider===`funasr`?!!g?.funasrAvailable:m?.transcription_provider===`multimodal`?!!(m?.multimodal_asr_api_key_configured&&String(m?.multimodal_asr_base_url||``).trim()&&String(m?.multimodal_asr_model||``).trim()):!!m?.siliconflow_asr_api_key_configured,ai=rr(o),oi=ir(o),si=ar(o),ci=or(o,ri),li=o.status===`checking`||o.status===`downloading`||o.status===`installing`;(0,S.useEffect)(()=>{if(!m||Pt!==`files`)return;let e=window.setTimeout(()=>{vr()},100);return()=>window.clearTimeout(e)},[Pt,vr]),(0,S.useEffect)(()=>{if(!n||!m||an.current===n.nonce)return;an.current=n.nonce;let e=ha(n.issueKey);e&&(Ft(e.category),Lt(e.targetKey))},[n,m]),(0,S.useEffect)(()=>{!r||!m||on.current!==r.nonce&&(on.current=r.nonce,Hn(r.presetId))},[r,m,cn]),(0,S.useEffect)(()=>{if(!It)return;let e=rn.current[It];if(!e)return;let t=window.setTimeout(()=>{e.scrollIntoView({behavior:`smooth`,block:`center`});let t=e.matches(`input, select, textarea, button`)?e:e.querySelector(`input, select, textarea, button`);t instanceof HTMLElement&&t.focus({preventScroll:!0}),zt(It),Lt(null)},80);return()=>window.clearTimeout(t)},[Pt,It]),(0,S.useEffect)(()=>{if(!Rt)return;let e=window.setTimeout(()=>zt(e=>e===Rt?null:e),2200);return()=>window.clearTimeout(e)},[Rt]),(0,S.useEffect)(()=>{Kt&&xr()},[Kt]);let ui=!!g?.funasrInstalled;if((0,S.useEffect)(()=>{!ui&&m?.transcription_provider===`funasr`&&h({...m,transcription_provider:`siliconflow`})},[ui]),(0,S.useEffect)(()=>{L.getEmbeddingPresets().then(e=>Ze(e.presets||{})).catch(()=>{})},[]),!m)return(0,R.jsx)(`section`,{className:`grid-card empty-state-card`,children:`正在加载设置...`});let di=m.transcription_provider===`siliconflow`,fi=m.transcription_provider===`multimodal`,pi=m.transcription_provider===`funasr`,mi=m.transcription_provider===`local`?1:2,hi=mi===1?`当前建议:本地 ASR / CPU 场景任务并发数设为 1,导图并发数设为 1。`:`当前建议:云 ASR 或 GPU 场景任务并发数设为 2,导图并发数设为 1。`,gi=Qt.filter(e=>e.status===`queued`).length,_i=Qt.filter(e=>e.status===`running`).length,vi=!!g?.localAsrInstalled,yi=!!g?.knowledgeDependenciesReady,bi=String(m?.siliconflow_embedding_base_url||Qq).trim(),xi=String(m?.siliconflow_embedding_model||$q).trim(),Si=Rr?!!(Lr&&bi&&xi):yi,Ci=!!(g?.chromadbBroken||g?.sentenceTransformersBroken||g?.modelscopeBroken),wi=Re?.required?.length?Re.required:Rr?[`chromadb`]:[`chromadb`,`sentence-transformers`],Ti=wi.join(` / `),Ei=wi.filter(e=>e===`chromadb`?!g?.chromadbInstalled&&!g?.chromadbBroken:e===`sentence-transformers`?!g?.sentenceTransformersInstalled&&!g?.sentenceTransformersBroken:e===`modelscope`?!g?.modelscopeInstalled&&!g?.modelscopeBroken:!1),Di=yi?`已安装`:Ci?`部分损坏`:`未安装`,Oi=yi?`installed`:Ci?`error`:`missing`,ki=yi?Rr?`chromadb 索引存储已就绪`:`向量库和本地模型依赖已就绪`:Ci?`检测到包导入异常`:`安装 ${Ti}`,Ai=et?.channels.filter(e=>e.needsUpdate)||[];et?.channels.find(e=>e.runtimeChannel===(g?.runtimeChannel||m.runtime_channel));let ji=et?.pipIndexes.map(e=>e.label).join(` / `)||`official / tsinghua / aliyun`,Mi=new Map((Et?.directories||[]).map(e=>[e.key,e])),Ni=Mi.get(`cache`)||null,Pi=Mi.get(`tasks`)||null,z=Mi.get(`logs`)||null,Fi=Mi.get(`runtime`)||null,Ii=!!(wr&&Et?.cleanup.serviceAvailable),Li=(Et?.cleanup.orphanTaskBytes||0)+(Et?.cleanup.cacheCandidateBytes||0),Ri=(Et?.cleanup.orphanTaskCount||0)+(Et?.cleanup.cacheCandidateCount||0);function zi(e){let t=ha(e);t&&(Ft(t.category),Lt(t.targetKey))}function B(e){y(!0),h(e),Tt({main:{status:`unknown`,message:``},visual:{status:`unknown`,message:``}})}function Bi(e){if(Object.keys(e).length===0){kn(null);return}kn(t=>({...t||{},...e}))}function Vi(){!m||!On||(B({...m,...On}),kn(null))}function Hi(e){if(!m)return;let t=m.defaults?.summary_system_prompt||``,n=m.defaults?.summary_user_prompt_template||``,r=e===`system`&&t||m.summary_system_prompt,i=e===`template`&&n||m.summary_user_prompt_template,a={};e===`system`&&m.summary_system_prompt!==r&&(a.summary_system_prompt=m.summary_system_prompt||``),e===`template`&&m.summary_user_prompt_template!==i&&(a.summary_user_prompt_template=m.summary_user_prompt_template||``),Bi(a),B({...m,summary_system_prompt:r,summary_user_prompt_template:i})}function Ui(e){if(!m)return;let t=m.defaults?.knowledge_note_system_prompt||m.knowledge_note_system_prompt,n=m.defaults?.knowledge_note_user_prompt_template||m.knowledge_note_user_prompt_template,r=e===`system`?t:m.knowledge_note_system_prompt,i=e===`template`?n:m.knowledge_note_user_prompt_template,a={};e===`system`&&m.knowledge_note_system_prompt!==r&&(a.knowledge_note_system_prompt=m.knowledge_note_system_prompt||``),e===`template`&&m.knowledge_note_user_prompt_template!==i&&(a.knowledge_note_user_prompt_template=m.knowledge_note_user_prompt_template||``),Bi(a),B({...m,knowledge_note_system_prompt:r,knowledge_note_user_prompt_template:i})}function Wi(e){if(!m)return;let t=m.defaults?.visual_note_system_prompt||m.visual_note_system_prompt,n=m.defaults?.visual_note_user_prompt_template||m.visual_note_user_prompt_template,r=m.defaults?.visual_frame_planning_prompt||m.visual_frame_planning_prompt,i=m.defaults?.visual_vlm_prompt||m.visual_vlm_prompt,a=e===`system`?t:m.visual_note_system_prompt,o=e===`template`?n:m.visual_note_user_prompt_template,s=e===`planning`?r:m.visual_frame_planning_prompt,c=e===`vlm`?i:m.visual_vlm_prompt,l={};e===`system`&&m.visual_note_system_prompt!==a&&(l.visual_note_system_prompt=m.visual_note_system_prompt||``),e===`template`&&m.visual_note_user_prompt_template!==o&&(l.visual_note_user_prompt_template=m.visual_note_user_prompt_template||``),e===`planning`&&m.visual_frame_planning_prompt!==s&&(l.visual_frame_planning_prompt=m.visual_frame_planning_prompt||``),e===`vlm`&&m.visual_vlm_prompt!==c&&(l.visual_vlm_prompt=m.visual_vlm_prompt||``),Bi(l),B({...m,visual_note_system_prompt:a,visual_note_user_prompt_template:o,visual_frame_planning_prompt:s,visual_vlm_prompt:c})}function Gi(e){if(m){if(e===`text`){B({...m,visual_note_mode:`text`,visual_evidence_enabled:!1,visual_evidence_use_llm:!1,visual_multimodal_enabled:!1});return}if(e===`visual`){B({...m,visual_note_mode:`frame_insert`,visual_evidence_enabled:!0,visual_evidence_use_llm:!1,visual_multimodal_enabled:!1});return}B({...m,visual_note_mode:`vlm_integrated`,visual_evidence_enabled:!0,visual_evidence_use_llm:!0,visual_multimodal_enabled:!0})}}function Ki(e){return String(e.host||``).trim()?e.transcription_provider===`siliconflow`&&!String(e.siliconflow_asr_base_url||``).trim()?{message:`请先填写 SiliconFlow Base URL。`,category:`transcription`,targetKey:`siliconflow_asr_base_url`}:e.llm_enabled&&!String(e.llm_base_url||``).trim()?{message:`请先填写 LLM API Base URL。`,category:`generation`,targetKey:`llm_base_url`}:Ji(e)||null:{message:`请先填写监听地址。`,category:`logs`,targetKey:`host`}}function qi(e,t){return t.every(t=>e.includes(t))}function Ji(e){let t=String(e.summary_user_prompt_template||``);if(!qi(t,[`{title}`,`{transcript}`,`{segments_json}`]))return{message:`摘要 User Template 需要保留 {title}、{transcript}、{segments_json} 变量,否则任务无法稳定生成摘要。`,category:`prompts`,targetKey:`summary_user_prompt_template`};for(let e of[`title`,`overview`,`bulletPoints`,`chapters`,`chapterGroups`])if(!t.includes(e))return{message:`摘要 User Template 需要保留 ${e} 输出字段约束。`,category:`prompts`,targetKey:`summary_user_prompt_template`};let n=String(e.knowledge_note_user_prompt_template||``);return qi(n,[`{title}`,`{summary_json}`])?n.includes(`knowledgeNoteMarkdown`)?qi(String(e.visual_frame_planning_prompt||``),[`{title}`,`{summary_json}`])?qi(String(e.visual_vlm_prompt||``),[`{title}`,`{timestamp}`])?qi(String(e.visual_note_user_prompt_template||``),[`{title}`,`{knowledge_note_markdown}`,`{visual_observations_json}`])?null:{message:`图文笔记 User Template 需要保留 {title}、{knowledge_note_markdown}、{visual_observations_json} 变量。`,category:`prompts`,targetKey:`visual_note_user_prompt_template`}:{message:`画面理解 Prompt 至少需要保留 {title} 与 {timestamp} 变量。`,category:`prompts`,targetKey:`visual_vlm_prompt`}:{message:`捕获帧规划 Prompt 至少需要保留 {title} 与 {summary_json} 变量。`,category:`prompts`,targetKey:`visual_frame_planning_prompt`}:{message:`知识笔记 User Template 需要保留 knowledgeNoteMarkdown 输出字段,否则任务会解析失败。`,category:`prompts`,targetKey:`knowledge_note_user_prompt_template`}:{message:`知识笔记 User Template 至少需要保留 {title} 与 {summary_json} 变量。`,category:`prompts`,targetKey:`knowledge_note_user_prompt_template`}}function Yi(e){let t={...e,device_preference:Xn(e.device_preference)};return String(t.knowledge_embedding_provider||``).trim().toLowerCase()===`siliconflow`&&(t.siliconflow_embedding_base_url=String(t.siliconflow_embedding_base_url||Qq).trim(),t.siliconflow_embedding_model=String(t.siliconflow_embedding_model||$q).trim()),e.siliconflow_asr_api_key_configured&&(!String(e.siliconflow_asr_api_key||``).trim()||eJ(e.siliconflow_asr_api_key))&&delete t.siliconflow_asr_api_key,e.multimodal_asr_api_key_configured&&(!String(e.multimodal_asr_api_key||``).trim()||eJ(e.multimodal_asr_api_key))&&delete t.multimodal_asr_api_key,e.llm_api_key_configured&&(!String(e.llm_api_key||``).trim()||eJ(e.llm_api_key))&&delete t.llm_api_key,e.knowledge_llm_api_key_configured&&(!String(e.knowledge_llm_api_key||``).trim()||eJ(e.knowledge_llm_api_key))&&delete t.knowledge_llm_api_key,e.siliconflow_embedding_api_key_configured&&(!String(e.siliconflow_embedding_api_key||``).trim()||eJ(e.siliconflow_embedding_api_key))&&delete t.siliconflow_embedding_api_key,e.visual_evidence_api_key_configured&&(!String(e.visual_evidence_api_key||``).trim()||eJ(e.visual_evidence_api_key))&&delete t.visual_evidence_api_key,e.twelvelabs_api_key_configured&&(!String(e.twelvelabs_api_key||``).trim()||eJ(e.twelvelabs_api_key))&&delete t.twelvelabs_api_key,e.siliconflow_embedding_api_key_configured&&(!String(e.siliconflow_embedding_api_key||``).trim()||eJ(e.siliconflow_embedding_api_key))&&delete t.siliconflow_embedding_api_key,t}async function Xi(e){if(e.preventDefault(),!m||b)return;if(!v){w(``);return}let t=Ki(m);if(t){w(t.message),Ft(t.category),Lt(t.targetKey);return}try{x(!0);let e=await L.updateSettings(Yi(m)),t=e.settings;h(nJ(t)),y(!1),w(e.message||`设置已保存`),(async()=>{try{let e=await L.getEnvironment({runtimeChannel:t.runtime_channel});_(e),a(t,e)}catch{a(t,null)}})()}catch(e){w(e instanceof Error?e.message:`保存设置失败`)}finally{x(!1)}}async function Zi(){if(!m)return;let e=`local-asr-${Date.now()}`,t=null;try{_e(!0),pe(`正在安装本地语音识别环境...`),he(``),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&he(n.log),n.done&&t&&(clearInterval(t),t=null)}catch{}},1500);let n=await L.installLocalAsr({installSessionId:e});t&&=(clearInterval(t),null);try{let t=await L.getInstallLog(e);t.log&&he(t.log)}catch{}pe(n.installed?`本地语音识别环境已安装`:`本地语音识别环境安装失败`);let r=n.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});if(_(r),n.installed)try{let e=await L.updateSettings({...Yi(m),transcription_provider:`local`});h(nJ(e.settings)),y(!1),w(e.message||`已切换为本地 ASR`),a(e.settings,r)}catch(e){pe(`本地 ASR 已安装,但切换默认转写方式失败:${e instanceof Error?e.message:`保存设置失败`}`)}i()}catch(e){t&&=(clearInterval(t),null),pe(e instanceof Error?e.message:`安装本地语音识别环境失败`)}finally{_e(!1)}}async function Qi(){if(!m)return;let e=`funasr-${Date.now()}`,t=null;try{Ce(!0),ye(`正在安装 FunASR 语音识别环境(含 torch 等依赖,可能需要较长时间)...`),xe(``),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&xe(n.log),n.done&&t&&(clearInterval(t),t=null)}catch(e){xe(t=>t+`\n[轮询异常: ${e instanceof Error?e.message:`network error`}]`)}},1500);let n=await L.installFunAsr({installSessionId:e});t&&=(clearInterval(t),null);try{let t=await L.getInstallLog(e);t.log&&xe(t.log)}catch{}ye(n.installed?`FunASR 语音识别环境已安装`:`FunASR 语音识别环境安装失败`);let r=n.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0});if(_(r),n.installed)try{let e=await L.updateSettings({...Yi(m),transcription_provider:`funasr`});h(nJ(e.settings)),y(!1),w(e.message||`已切换为 FunASR`),a(e.settings,r)}catch(e){ye(`FunASR 已安装,但切换默认转写方式失败:${e instanceof Error?e.message:`保存设置失败`}`)}i()}catch(e){t&&=(clearInterval(t),null),ye(e instanceof Error?e.message:`安装 FunASR 语音识别环境失败`)}finally{Ce(!1)}}async function $i(){if(!m)return;let e=`knowledge-deps-${Date.now()}`,t=null;try{Le(!0),Ne(`正在安装知识库依赖...`),Fe(``),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&Fe(n.log),n.done&&t&&(clearInterval(t),t=null)}catch{}},1500);let n=await L.installKnowledgeDependencies({runtime_channel:m.runtime_channel,provider:m.knowledge_embedding_provider||`local_huggingface`,reinstall:!!yi||Ci,installSessionId:e});t&&=(clearInterval(t),null);try{let t=await L.getInstallLog(e);t.log&&Fe(t.log)}catch{}Ne(n.installed?`知识库依赖已安装并完成检测`:`知识库依赖安装后仍未完全就绪`),_(n.environment||await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0})),await ea(),i()}catch(e){t&&=(clearInterval(t),null),Ne(e instanceof Error?e.message:`安装知识库依赖失败`)}finally{Le(!1)}}async function ea(){if(m)try{ze(await L.getKnowledgeRequirements(m.knowledge_embedding_provider||`local_huggingface`))}catch(e){console.error(`Failed to fetch knowledge requirements:`,e)}}async function ta(){_(await L.getEnvironment({runtimeChannel:m?.runtime_channel,refresh:!0})),await ea(),i()}async function na(){if(!m)return;let e=`emb-dl-${Date.now()}`;try{Ve(!0),Ye(!1),qe(``),Ge(`正在安装依赖并下载模型...`);let t=await L.downloadEmbeddingModel({provider:m.knowledge_embedding_provider||`local_huggingface`,model:m.knowledge_embedding_model,hf_endpoint:m.hf_endpoint,installSessionId:e});try{qe((await L.getInstallLog(e)).log||t.stdoutTail||``)}catch{qe(t.stdoutTail||``)}Ge(t.downloaded?`模型下载完成,可以测试了。`:`下载失败:${t.detail}`)}catch(e){Ge(e instanceof Error?e.message:`下载模型失败`)}finally{Ve(!1)}}async function ra(){if(m)try{Ue(!0),qe(``),Ge(m.knowledge_embedding_provider===`siliconflow`?`正在请求硅基流动 Embedding API...`:`正在加载并验证 Embedding 模型...`);let e=m.knowledge_embedding_provider||`local_huggingface`,t=await L.testEmbeddingModel({provider:e,model:e===`siliconflow`?xi:m.knowledge_embedding_model,hf_endpoint:m.hf_endpoint,api_key:e===`siliconflow`&&!eJ(m.siliconflow_embedding_api_key)?m.siliconflow_embedding_api_key:void 0,base_url:e===`siliconflow`?bi:void 0});qe(t.stdoutTail||``),t.verified?(Ye(!0),Ge(t.detail||`模型验证成功!`)):(Ye(!1),Ge(`验证失败:${t.detail}`))}catch(e){Ye(!1),Ge(e instanceof Error?e.message:`验证模型失败`)}finally{Ue(!1)}}async function ia(){if(!(!m||we))try{Te(!0),ke(``),je(``);let e=window.desktop?.bilibili;if(!e){De(`正在生成 B 站扫码登录二维码...`);let e=await L.createBilibiliCookieQrcode(),t=await zq.toDataURL(e.url,{margin:1,width:180,color:{dark:`#111111`,light:`#ffffff`}});ke(e.qrcodeKey),je(t),De(`请用手机 B 站扫码,并在手机上确认登录。`);return}De(`请在新窗口登录 B 站,登录成功后会自动保存 cookies...`);let t=await e.captureLoginCookies(),n=await L.updateSettings({ytdlp_cookies_file:t.cookiesFile,ytdlp_cookies_browser:``});h(nJ(n.settings)),y(!1),w(n.message||`设置已保存`),De(`B 站登录态已保存${t.browser?`(${t.browser})`:``},捕获 ${t.cookieCount} 条 cookies。`),a(n.settings,g)}catch(e){De(e instanceof Error?e.message:`捕获 B 站登录态失败,请按教程手动导出 cookies.txt。`)}finally{Te(!1)}}function aa(e){if(!m)return null;if(e===`main`)return{llm_enabled:m.llm_enabled,llm_provider:m.llm_provider,llm_base_url:m.llm_base_url,llm_model:m.llm_model,...m.llm_api_key.trim()&&!eJ(m.llm_api_key)?{llm_api_key:m.llm_api_key}:{}};let t=String(m.visual_evidence_api_key||``).trim(),n=String(m.llm_api_key||``).trim();return{llm_test_scope:`visual`,llm_enabled:m.visual_multimodal_enabled,llm_provider:m.visual_vlm_provider||m.llm_provider,llm_base_url:m.visual_evidence_base_url||m.llm_base_url,llm_model:m.visual_evidence_model||m.llm_model,...!t||eJ(t)?n&&!eJ(n)?{llm_api_key:n}:{}:{llm_api_key:t}}}async function oa(e){let t=aa(e);if(!t)throw Error(`模型配置尚未加载。`);return L.testLlmConnection(t)}async function sa(){if(!(!m||St))try{Ct(!0),xt(e=>e+1),yt(`正在测试 LLM 连接与 JSON 输出...`);let e=await oa(`main`),t=e.jsonPreview||e.responsePreview,n=t?`,示例:${t}`:``;yt(`${e.message}${n}`),Tt(t=>({...t,main:{status:`available`,message:e.message}}))}catch(e){let t=e instanceof Error?e.message:`LLM 连接测试失败`;yt(t),Tt(e=>({...e,main:{status:`unavailable`,message:t}}))}finally{Ct(!1)}}async function ca(){if(!(!m||St))try{Ct(!0),xt(e=>e+1),yt(`正在测试知识库 LLM 连接与 JSON 输出...`);let e=await L.testLlmConnection({llm_test_scope:`knowledge`,llm_enabled:m.knowledge_llm_enabled,llm_provider:m.knowledge_llm_provider,llm_base_url:m.knowledge_llm_base_url,llm_model:m.knowledge_llm_model,...m.knowledge_llm_api_key.trim()&&!eJ(m.knowledge_llm_api_key)?{llm_api_key:m.knowledge_llm_api_key}:{}}),t=e.jsonPreview||e.responsePreview,n=t?`,示例:${t}`:``;yt(`${e.message}${n}`)}catch(e){yt(e instanceof Error?e.message:`知识库 LLM 连接测试失败`)}finally{Ct(!1)}}async function la(){if(!(!m||St))try{Ct(!0),xt(e=>e+1),yt(`正在测试视觉模型连接与 JSON 输出...`);let e=await oa(`visual`),t=e.jsonPreview||e.responsePreview,n=t?`,示例:${t}`:``;yt(`${e.message}${n}`),Tt(t=>({...t,visual:{status:`available`,message:e.message}}))}catch(e){let t=e instanceof Error?e.message:`视觉模型连接测试失败`;yt(t),Tt(e=>({...e,visual:{status:`unavailable`,message:t}}))}finally{Ct(!1)}}function ua(){let e=Ht;Ut(null),e&&da(e)}async function da(e){if(!m||St)return;let t=sn.current+1;sn.current=t,Tt(t=>({...t,[e]:{status:`checking`,message:``}}));try{let n=await oa(e);if(sn.current!==t)return;Tt(t=>({...t,[e]:{status:`available`,message:n.message}}))}catch(n){if(sn.current!==t)return;Tt(t=>({...t,[e]:{status:`unavailable`,message:n instanceof Error?n.message:`模型不可用`}}))}}async function fa(){if(!(!m||gt))try{_t(!0),ht(`正在测试 ASR 连接...`);let e=await L.testAsrConnection({transcription_provider:m.transcription_provider,siliconflow_asr_base_url:m.siliconflow_asr_base_url,siliconflow_asr_model:m.siliconflow_asr_model,...m.siliconflow_asr_api_key.trim()&&!eJ(m.siliconflow_asr_api_key)?{siliconflow_asr_api_key:m.siliconflow_asr_api_key}:{},multimodal_asr_base_url:m.multimodal_asr_base_url,multimodal_asr_model:m.multimodal_asr_model,...m.multimodal_asr_api_key.trim()&&!eJ(m.multimodal_asr_api_key)?{multimodal_asr_api_key:m.multimodal_asr_api_key}:{}}),t=e.responsePreview?`,示例:${e.responsePreview}`:``;ht(`${e.message}${t}`)}catch(e){ht(e instanceof Error?e.message:`ASR 连接测试失败`)}finally{_t(!1)}}let pa=$n(m,g);function V(e){return t=>{rn.current[e]=t}}function ma(e,t){Ft(e),Lt(t),Gt(``)}function ha(e){return m?e===`siliconflow_asr_api_key`?{category:`transcription`,targetKey:`siliconflow_asr_api_key`}:e===`multimodal_asr_base_url`?{category:`transcription`,targetKey:`multimodal_asr_base_url`}:e===`local_asr_runtime`?{category:`runtime`,targetKey:`local_asr_runtime`}:e===`auto_mindmap_requires_llm`?{category:`generation`,targetKey:`llm_enabled`}:e===`knowledge_dependencies`?{category:`runtime`,targetKey:`knowledge_runtime`}:e===`siliconflow_embedding_api_key`?{category:`knowledge`,targetKey:`siliconflow_embedding_api_key`}:e===`knowledge_llm_configuration`?String(m.knowledge_llm_mode||`same_as_main`).trim().toLowerCase()===`custom`?m.knowledge_llm_enabled?String(m.knowledge_llm_base_url||``).trim()?tJ(m.knowledge_llm_api_key,m.knowledge_llm_api_key_configured)?String(m.knowledge_llm_model||``).trim()?{category:`knowledge`,targetKey:`knowledge_llm_base_url`}:{category:`knowledge`,targetKey:`knowledge_llm_model`}:{category:`knowledge`,targetKey:`knowledge_llm_api_key`}:{category:`knowledge`,targetKey:`knowledge_llm_base_url`}:{category:`knowledge`,targetKey:`knowledge_llm_enabled`}:m.llm_enabled?String(m.llm_base_url||``).trim()?tJ(m.llm_api_key,m.llm_api_key_configured)?String(m.llm_model||``).trim()?{category:`knowledge`,targetKey:`knowledge_llm_mode`}:{category:`generation`,targetKey:`llm_model`}:{category:`generation`,targetKey:`llm_api_key`}:{category:`generation`,targetKey:`llm_base_url`}:{category:`generation`,targetKey:`llm_enabled`}:e===`llm_configuration`?String(m.llm_base_url||``).trim()?tJ(m.llm_api_key,m.llm_api_key_configured)?String(m.llm_model||``).trim()?{category:`generation`,targetKey:`llm_base_url`}:{category:`generation`,targetKey:`llm_model`}:{category:`generation`,targetKey:`llm_api_key`}:{category:`generation`,targetKey:`llm_base_url`}:e===`ytdlp_cookies_browser`||e===`ytdlp_cookies_file`?{category:`video`,targetKey:`ytdlp_cookies_file`}:null:null}return(0,R.jsxs)(`div`,{className:`settings-page-wrapper`,children:[(0,R.jsx)(Vx,{notices:[{id:`settings-save-status`,message:C},{id:`settings-cuda-status`,message:T},{id:`settings-local-asr-status`,message:fe},{id:`settings-funasr-status`,message:ve},{id:`settings-knowledge-deps-status`,message:Me},{id:`settings-runtime-status`,message:nt},{id:`settings-asr-test-status`,message:mt},{id:`settings-llm-test-status`,message:vt,version:bt},{id:`settings-storage-status`,message:Mt},{id:`settings-backend-error`,message:t.backend?.lastError||``,tone:`error`},{id:`settings-service-status`,message:ft}]}),(0,R.jsxs)(`aside`,{className:`settings-nav`,ref:en,children:[(0,R.jsxs)(`div`,{className:`settings-nav-header`,children:[(0,R.jsx)(`span`,{className:`settings-nav-label-small`,children:`BiliSum`}),(0,R.jsxs)(`div`,{className:`settings-nav-brand-card`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-brand-copy`,children:[(0,R.jsx)(`span`,{className:`settings-nav-brand-kicker`,children:`设置`}),(0,R.jsx)(`strong`,{children:`管理应用与运行配置`}),(0,R.jsx)(`p`,{children:`调整目录、模型、服务与环境配置。`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-brand-metrics`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-metric`,children:[(0,R.jsx)(`span`,{children:`服务`}),(0,R.jsx)(`strong`,{children:wr?`在线`:Sr?`启动中`:`离线`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-metric`,children:[(0,R.jsx)(`span`,{children:`设备`}),(0,R.jsx)(`strong`,{children:Zn(m.whisper_device)})]})]})]})]}),(0,R.jsxs)(`div`,{className:`settings-nav-list`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-group`,children:[(0,R.jsx)(`span`,{className:`settings-nav-group-label`,children:`工作流`}),(0,R.jsx)(`nav`,{className:`settings-nav-links`,children:Or.map(e=>(0,R.jsxs)(`button`,{className:`settings-nav-item ${Pt===e.id?`active`:``}`,type:`button`,onClick:()=>Ft(e.id),children:[(0,R.jsx)(`span`,{className:`settings-nav-icon`,children:e.icon}),(0,R.jsxs)(`span`,{className:`settings-nav-copy`,children:[(0,R.jsx)(`span`,{className:`settings-nav-label`,children:e.label}),(0,R.jsx)(`span`,{className:`settings-nav-description`,children:e.description})]})]},e.id))})]}),(0,R.jsxs)(`div`,{className:`settings-nav-group`,children:[(0,R.jsx)(`span`,{className:`settings-nav-group-label`,children:`系统`}),(0,R.jsx)(`nav`,{className:`settings-nav-links`,children:kr.map(e=>(0,R.jsxs)(`button`,{className:`settings-nav-item ${Pt===e.id?`active`:``}`,type:`button`,onClick:()=>Ft(e.id),children:[(0,R.jsx)(`span`,{className:`settings-nav-icon`,children:e.icon}),(0,R.jsxs)(`span`,{className:`settings-nav-copy`,children:[(0,R.jsx)(`span`,{className:`settings-nav-label`,children:e.label}),(0,R.jsx)(`span`,{className:`settings-nav-description`,children:e.description})]})]},e.id))})]})]}),(0,R.jsxs)(`div`,{className:`settings-nav-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button settings-save-btn`,type:`button`,disabled:b||!v,onClick:async e=>{e.preventDefault(),await Xi(e)},children:b?`保存中...`:v?`保存设置`:`已保存`}),(0,R.jsxs)(`div`,{className:`settings-nav-summary`,children:[(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`运行环境`}),(0,R.jsx)(`strong`,{children:g?.runtimeChannel||m.runtime_channel||`base`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`LLM`}),(0,R.jsx)(`strong`,{children:Vr?`已配置`:m.llm_enabled?`待补全`:`关闭`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`自动导图`}),(0,R.jsx)(`strong`,{children:m.auto_generate_mindmap?`开启`:`关闭`})]}),(0,R.jsxs)(`div`,{className:`settings-nav-summary-row`,children:[(0,R.jsx)(`span`,{children:`知识库`}),(0,R.jsx)(`strong`,{children:m.knowledge_enabled?Si&&yi?`就绪`:`待配置`:`关闭`})]})]})]})]}),(0,R.jsx)(`main`,{className:`settings-content`,children:(0,R.jsxs)(`div`,{className:`settings-content-scroll`,ref:tn,children:[(0,R.jsxs)(`section`,{className:`settings-search-panel`,"aria-label":`搜索设置`,children:[(0,R.jsxs)(`div`,{className:`settings-search-box`,children:[(0,R.jsx)(Nr,{className:`settings-search-icon`,"aria-hidden":`true`}),(0,R.jsx)(`input`,{className:`settings-search-input`,type:`search`,value:Wt,onChange:e=>Gt(e.target.value),placeholder:`搜索设置,例如 API Key、输出目录、知识笔记、并发、Cookies`}),Wt?(0,R.jsx)(`button`,{className:`settings-search-clear`,type:`button`,onClick:()=>Gt(``),children:`清空`}):null]}),Ar?(0,R.jsx)(`div`,{className:`settings-search-results`,role:`listbox`,"aria-label":`设置搜索结果`,children:Mr.length?Mr.map(e=>(0,R.jsxs)(`button`,{className:`settings-search-result`,type:`button`,role:`option`,onClick:()=>ma(e.category,e.targetKey),children:[(0,R.jsxs)(`span`,{className:`settings-search-result-main`,children:[(0,R.jsx)(`strong`,{children:e.title}),(0,R.jsx)(`span`,{children:e.description})]}),(0,R.jsx)(`span`,{className:`settings-search-result-category`,children:e.categoryLabel})]},`${e.category}:${e.targetKey}`)):(0,R.jsx)(`div`,{className:`settings-search-empty`,children:`没有找到相关设置,换个关键词试试。`})}):null]}),(0,R.jsxs)(`header`,{className:`settings-page-hero`,children:[(0,R.jsxs)(`div`,{className:`settings-page-hero-copy`,children:[(0,R.jsx)(`span`,{className:`settings-page-kicker`,children:`Settings`}),(0,R.jsx)(`h1`,{children:Dr.label}),(0,R.jsx)(`p`,{children:Dr.description})]}),(0,R.jsxs)(`div`,{className:`settings-page-hero-meta`,children:[(0,R.jsx)(`span`,{className:`settings-hero-chip ${wr?`is-success`:Sr?`is-warning`:`is-danger`}`,children:wr?`服务在线`:Sr?`启动中...`:`服务离线`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${pa.hasBlockingIssues?`is-danger`:pa.isConfigured?`is-success`:`is-warning`}`,children:pa.hasBlockingIssues?`配置缺失`:pa.isConfigured?`配置完整`:`配置待补全`}),(0,R.jsx)(`span`,{className:`settings-hero-chip`,children:g?.runtimeChannel||m.runtime_channel||`base`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${(m.transcription_provider===`funasr`?m.funasr_device===`cuda`:g?.cudaAvailable)?`is-success`:``}`,children:m.transcription_provider===`funasr`?m.funasr_device===`cuda`?`GPU (CUDA)`:`CPU`:m.transcription_provider===`local`?Zn(m.whisper_device):g?.cudaAvailable?`CUDA Ready`:`CPU Only`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${Vr?`is-success`:``}`,children:Vr?`LLM 已配置`:m.llm_enabled?`LLM 待补全`:`LLM 关闭`}),(0,R.jsx)(`span`,{className:`settings-hero-chip ${m.knowledge_enabled&&Si&&yi?`is-success`:m.knowledge_enabled&&g?.runtimeReady!==void 0?`is-warning`:``}`,children:!g?.runtimeReady&&!g?.runtimeError?`检测中...`:m.knowledge_enabled?Si&&yi?`知识库就绪`:`知识库待配置`:`知识库关闭`})]})]}),pa.checked?(0,R.jsxs)(`section`,{className:`settings-config-health-card tone-${pa.state}`,children:[(0,R.jsxs)(`div`,{className:`settings-config-health-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`Setup Health`}),(0,R.jsx)(`h3`,{children:pa.hasBlockingIssues?`先补全关键配置,再开始处理视频`:pa.isConfigured?`当前配置状态良好`:`建议补全增强能力配置`}),(0,R.jsx)(`p`,{children:pa.summary})]}),pa.isConfigured?null:(0,R.jsx)(`div`,{className:`settings-config-health-list`,children:pa.issues.map(e=>(0,R.jsxs)(`button`,{className:`settings-config-health-item`,type:`button`,onClick:()=>zi(e.key),children:[(0,R.jsx)(`strong`,{children:e.title}),(0,R.jsx)(`span`,{children:e.description})]},e.key))})]}):null,Pt===`overview`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`设置总览`}),(0,R.jsx)(`p`,{children:`查看当前配置、运行状态和常用操作。`})]}),(0,R.jsxs)(`div`,{className:`settings-story-card`,children:[(0,R.jsxs)(`div`,{className:`settings-story-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`概览`}),(0,R.jsx)(`h3`,{children:`当前配置与运行状态`}),(0,R.jsx)(`p`,{children:`这里展示运行环境、模型、摘要模式和服务状态。排障时请切换到环境检测或日志。`})]}),(0,R.jsxs)(`div`,{className:`settings-story-stats`,children:[(0,R.jsxs)(`div`,{className:`settings-story-stat`,children:[(0,R.jsx)(`span`,{children:`服务端口`}),(0,R.jsxs)(`strong`,{children:[m.host,`:`,m.port]})]}),(0,R.jsxs)(`div`,{className:`settings-story-stat`,children:[(0,R.jsx)(`span`,{children:`转写`}),(0,R.jsx)(`strong`,{children:m.transcription_provider===`siliconflow`?`SiliconFlow API`:m.transcription_provider===`funasr`?`FunASR`:m.transcription_provider===`multimodal`?`多模态 ASR`:`Whisper 转写`})]}),(0,R.jsxs)(`div`,{className:`settings-story-stat`,children:[(0,R.jsx)(`span`,{children:`摘要模式`}),(0,R.jsx)(`strong`,{children:m.summary_mode===`llm`?`LLM 智能摘要`:`抽取式摘要`})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-grid`,children:[(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsxs)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,R.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,R.jsx)(`path`,{d:`M12 6v6l4 2`})]})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`服务状态`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${wr?`text-success`:`text-danger`}`,children:wr?`运行中`:`已停止`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsxs)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,R.jsx)(`rect`,{x:`2`,y:`3`,width:`20`,height:`14`,rx:`2`}),(0,R.jsx)(`line`,{x1:`8`,y1:`21`,x2:`16`,y2:`21`})]})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`运行环境`}),(0,R.jsx)(`strong`,{className:`overview-status-value`,children:g?.runtimeChannel||m.runtime_channel||`base`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsx)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,R.jsx)(`polyline`,{points:`22 12 18 12 15 21 9 3 6 12 2 12`})})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`推理设备`}),(0,R.jsx)(`strong`,{className:`overview-status-value`,children:m.transcription_provider===`local`?Zn(m.whisper_device):m.transcription_provider===`funasr`?Zn(m.funasr_device):`云端识别`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsx)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,R.jsx)(`path`,{d:`M20.2 7.8l-7.7 7.7a4 4 0 0 1-5.7 0l-3-3a1 1 0 0 1 1.4-1.4l3 3a2 2 0 0 0 2.8 0l7.7-7.7a1 1 0 0 1 1.4 1.4z`})})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`LLM 摘要`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${m.llm_enabled?`text-success`:``}`,children:m.llm_enabled?`已启用`:`已关闭`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsx)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:(0,R.jsx)(`path`,{d:`M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z`})})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`语音识别服务`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${ii?`text-success`:`text-danger`}`,children:m.transcription_provider===`siliconflow`?ii?`硅基流动已配置`:`硅基流动待补全`:m.transcription_provider===`multimodal`?ii?`多模态 ASR 已配置`:`多模态 ASR 待补全`:m.transcription_provider===`funasr`?ui?`FunASR 已安装`:`FunASR 未安装`:vi?`Whisper 已安装`:`Whisper 未安装`})]})]}),(0,R.jsxs)(`div`,{className:`overview-status-card`,children:[(0,R.jsx)(`div`,{className:`overview-status-icon`,children:(0,R.jsxs)(`svg`,{width:`24`,height:`24`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,children:[(0,R.jsx)(`path`,{d:`M4 5h16`}),(0,R.jsx)(`path`,{d:`M4 12h10`}),(0,R.jsx)(`path`,{d:`M4 19h16`}),(0,R.jsx)(`circle`,{cx:`18`,cy:`12`,r:`2`})]})}),(0,R.jsxs)(`div`,{className:`overview-status-info`,children:[(0,R.jsx)(`span`,{className:`overview-status-label`,children:`自动导图`}),(0,R.jsx)(`strong`,{className:`overview-status-value ${ni?`text-success`:``}`,children:ni?`已启用`:`已关闭`})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-section`,children:[(0,R.jsx)(`h3`,{className:`overview-section-title`,children:`环境信息`}),(0,R.jsxs)(`div`,{className:`overview-info-grid`,children:[(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`Python`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:g?.pythonVersion||`-`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`Torch`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.torchInstalled?`text-success`:``}`,children:g?.torchInstalled?g?.torchVersion||`已安装`:`未安装`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`GPU`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.cudaAvailable?`text-success`:``}`,children:g?.cudaAvailable?g?.gpuName||`已就绪`:`未检测到`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`yt-dlp`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:g?.ytDlpVersion||`-`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:pi?`FunASR`:`Whisper`}),(0,R.jsx)(`span`,{className:`overview-info-value ${pi?g?.funasrInstalled?`text-success`:``:g?.localAsrInstalled?`text-success`:``}`,children:pi?g?.funasrInstalled?g?.funasrVersion||`已安装`:`未安装`:g?.localAsrInstalled?g?.localAsrVersion||`已安装`:`未安装`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`FFmpeg`}),(0,R.jsx)(`span`,{className:`overview-info-value ${g?.ffmpegLocation?`text-success`:``}`,children:g?.ffmpegLocation?`已安装`:`未安装`})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-section`,children:[(0,R.jsx)(`h3`,{className:`overview-section-title`,children:`版本信息`}),(0,R.jsxs)(`div`,{className:`overview-info-grid`,children:[(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`应用版本`}),(0,R.jsxs)(`span`,{className:`overview-info-value`,children:[`v`,t.version||`-`]})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`监听地址`}),(0,R.jsxs)(`span`,{className:`overview-info-value`,children:[m.host,`:`,m.port]})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`语言`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:m.language===`zh`?`中文`:m.language===`en`?`English`:`日本語`})]}),(0,R.jsxs)(`div`,{className:`overview-info-item`,children:[(0,R.jsx)(`span`,{className:`overview-info-label`,children:`ASR 模型`}),(0,R.jsx)(`span`,{className:`overview-info-value`,children:m.transcription_provider===`local`?m.fixed_model:m.transcription_provider===`multimodal`?m.multimodal_asr_model:m.siliconflow_asr_model})]})]})]}),(0,R.jsxs)(`div`,{className:`overview-section`,children:[(0,R.jsx)(`h3`,{className:`overview-section-title`,children:`快速操作`}),(0,R.jsxs)(`div`,{className:`overview-actions`,children:[(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`runtime`),children:`运行环境维护`}),(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`logs`),children:`查看日志`}),(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`transcription`),children:`转写设置`}),(0,R.jsx)(`button`,{className:`tertiary-button`,type:`button`,onClick:()=>Ft(`generation`),children:`摘要设置`})]})]})]}),Pt===`files`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`输出与文件`}),(0,R.jsx)(`p`,{children:`管理导出位置、应用数据目录和本地空间占用。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`data_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`数据目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.data_dir),onChange:e=>B({...m,data_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`存储视频摘要和元数据`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`cache_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`缓存目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.cache_dir),onChange:e=>B({...m,cache_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`临时缓存文件`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`tasks_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`任务目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.tasks_dir),onChange:e=>B({...m,tasks_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`任务历史记录`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`output_dir`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`输出目录`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:String(m.output_dir),onChange:e=>B({...m,output_dir:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`手动导出的 Markdown / Obsidian 笔记会写入这里。`})]})]})]}),Pt===`files`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`文件管理`}),(0,R.jsx)(`p`,{children:`查看本地空间占用,并安全清理缓存和孤儿任务目录。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-overview`,ref:V(`storage_cleanup`),children:[(0,R.jsxs)(`div`,{className:`settings-update-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`Storage`}),(0,R.jsx)(`h3`,{children:`当前本地占用`}),(0,R.jsxs)(`p`,{children:[`已托管空间约 `,aJ(Et?.totals.managedBytes||0),`, 共 `,oJ(Et?.totals.managedFiles||0,`文件`),`,`,oJ(Et?.totals.managedDirectories||0,`目录`),`。`]})]}),(0,R.jsxs)(`div`,{className:`settings-update-badges`,children:[(0,R.jsx)(`span`,{className:`helper-chip`,children:Ot?`扫描中...`:`统计已就绪`}),(0,R.jsx)(`span`,{className:`helper-chip ${Ii?`status-success`:`status-pending`}`,children:Ii?`可校验引用关系`:`服务离线,禁用清理`}),(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`可回收 `,aJ(Li)]})]})]}),(0,R.jsx)(`div`,{className:`settings-storage-grid`,children:(Et?.directories||[]).map(e=>(0,R.jsxs)(`article`,{className:`settings-storage-card`,children:[(0,R.jsxs)(`div`,{className:`settings-storage-card-head`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:e.label}),(0,R.jsx)(`strong`,{children:aJ(e.sizeBytes)})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>void yr(e.key),children:`打开目录`})]}),(0,R.jsx)(`p`,{className:`settings-storage-path`,children:e.path}),(0,R.jsxs)(`div`,{className:`settings-storage-meta`,children:[(0,R.jsx)(`span`,{children:e.exists?`目录存在`:`目录不存在`}),(0,R.jsx)(`span`,{children:oJ(e.fileCount,`文件`)}),(0,R.jsx)(`span`,{children:oJ(e.directoryCount,`子目录`)})]})]},e.key))}),(0,R.jsxs)(`div`,{className:`settings-storage-detail-grid`,children:[(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`缓存目录`}),(0,R.jsx)(`strong`,{children:aJ(Ni?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:"当前仅把 `uploads` 和 `covers` 视为可安全回收的缓存内容,删除后必要资源会自动重新生成。"}),(0,R.jsxs)(`div`,{className:`settings-storage-meta`,children:[(0,R.jsx)(`span`,{children:oJ(Et?.cleanup.cacheCandidateCount||0,`可清理项`)}),(0,R.jsxs)(`span`,{children:[`预计释放 `,aJ(Et?.cleanup.cacheCandidateBytes||0)]})]})]}),(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`任务结果`}),(0,R.jsx)(`strong`,{children:aJ(Pi?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:`仅识别目录名像任务 ID、但数据库中已不存在的孤儿任务目录,不会删除仍被引用的结果文件。`}),(0,R.jsxs)(`div`,{className:`settings-storage-meta`,children:[(0,R.jsx)(`span`,{children:oJ(Et?.cleanup.orphanTaskCount||0,`孤儿目录`)}),(0,R.jsxs)(`span`,{children:[`预计释放 `,aJ(Et?.cleanup.orphanTaskBytes||0)]})]})]}),(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`日志目录`}),(0,R.jsx)(`strong`,{children:aJ(z?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:`日志仅展示体积和位置,首版不提供清空操作,避免误删排障信息。`})]}),(0,R.jsxs)(`article`,{className:`settings-storage-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`运行环境目录`}),(0,R.jsx)(`strong`,{children:aJ(Fi?.sizeBytes||0)}),(0,R.jsx)(`p`,{children:`运行环境目录只做统计,不参与清理,避免影响 Python、Torch 或 CUDA 运行环境。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-update-next-step`,children:[(0,R.jsx)(`strong`,{children:`清理说明`}),(0,R.jsx)(`span`,{children:Ii?Ri>0?`预计可安全清理 ${Ri} 项内容,释放约 ${aJ(Li)}。`:`当前没有发现可安全清理的缓存或孤儿任务目录。`:`当前服务离线,无法确认哪些任务目录仍被数据库引用,因此已禁用一键清理。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:Ot||At,onClick:()=>void vr(),children:Ot?`扫描中...`:`刷新统计`}),(0,R.jsx)(`button`,{className:`secondary-button danger-button`,type:`button`,disabled:!Ii||At||Ot,onClick:()=>void br(),children:At?`清理中...`:`一键清理孤儿项`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>void yr(`data`),children:`打开数据目录`})]})]}),Pt===`video`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`视频获取`}),(0,R.jsx)(`p`,{children:`处理 B 站登录态、下载缓存和转写临时音频。遇到风控、登录或重复下载问题时先看这里。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`ytdlp_cookies_file`?`is-highlighted`:``}`,ref:V(`ytdlp_cookies_file`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`B 站 Cookies 文件`}),(0,R.jsxs)(`div`,{className:`settings-input-action-row`,children:[(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.ytdlp_cookies_file||``,onChange:e=>B({...m,ytdlp_cookies_file:e.target.value}),placeholder:`C:\\\\Users\\\\you\\\\Downloads\\\\cookies.txt`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:we,onClick:()=>void ia(),children:we?`获取中...`:`登录获取`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`推荐通过提示弹窗打开 B 站登录窗口自动生成;也可以手动填写从已登录浏览器导出的 cookies.txt。`}),Ae?(0,R.jsxs)(`div`,{className:`settings-cookie-qrcode`,children:[(0,R.jsx)(`img`,{src:Ae,alt:`B 站扫码登录二维码`}),(0,R.jsx)(`span`,{children:`用手机 B 站扫码确认后会自动写入 cookies 文件。`})]}):null,Ee?(0,R.jsx)(`span`,{className:`settings-input-caption`,children:Ee}):null]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`enable_cache`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用下载缓存`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.enable_cache?`true`:`false`,onChange:e=>B({...m,enable_cache:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`true`,children:`开启`}),(0,R.jsx)(`option`,{value:`false`,children:`关闭`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`开启后会复用封面、上传文件和部分中间结果,适合反复处理同一批视频。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`preserve_temp_audio`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`保留临时音频`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.preserve_temp_audio?`true`:`false`,onChange:e=>B({...m,preserve_temp_audio:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`不保留`}),(0,R.jsx)(`option`,{value:`true`,children:`保留`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`排查转写问题时可以临时开启;日常关闭能减少磁盘占用。`})]})]})]}),Pt===`transcription`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`语音转文字`}),(0,R.jsx)(`p`,{children:`配置视频音频如何转成文本:云端 ASR 更省心,本地 ASR 更依赖运行环境和设备。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`转写方式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,ref:V(`transcription_provider`),value:m.transcription_provider,onChange:e=>B({...m,transcription_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`siliconflow`,children:`硅基流动 API`}),(0,R.jsx)(`option`,{value:`multimodal`,children:`多模态 ASR(第三方)`}),(0,R.jsxs)(`option`,{value:`funasr`,disabled:!ui,children:[`FunASR(本地)`,ui?``:`(需先安装)`]}),(0,R.jsx)(`option`,{value:`local`,disabled:!vi,children:`Whisper 转写(需先安装)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`默认推荐云端模式(硅基流动的语音识别是免费的!只需要注册然后填上apikey就可以用了)。`})]}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`优先使用 UP 主字幕`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`开启后,BiliSum 会尝试从 B 站 API 获取视频自带字幕(CC 字幕、UP 主上传字幕)。如果字幕存在且完整,将跳过 ASR 转写,节省时间。字幕不存在时自动使用 ASR。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:m.prefer_bilibili_subtitle||!1,onChange:e=>B({...m,prefer_bilibili_subtitle:e.target.checked})}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),di?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`siliconflow_asr_base_url`?`is-highlighted`:``}`,ref:V(`siliconflow_asr_base_url`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`SiliconFlow Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_asr_base_url,onChange:e=>B({...m,siliconflow_asr_base_url:e.target.value}),placeholder:`https://api.siliconflow.cn/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:"默认保持 `https://api.siliconflow.cn/v1` 即可。"})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`siliconflow_asr_api_key`?`is-highlighted`:``}`,ref:V(`siliconflow_asr_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`SiliconFlow API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.siliconflow_asr_api_key,onFocus:rJ,onChange:e=>B({...m,siliconflow_asr_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(qq,{})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`siliconflow_asr_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`语音转写 ASR 模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_asr_model,onChange:e=>B({...m,siliconflow_asr_model:e.target.value}),placeholder:`TeleAI/TeleSpeechASR`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`推荐使用:TeleAI/TeleSpeechASR`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`siliconflow_asr_chunk_duration_seconds`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`ASR 切片时长(秒)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:60,max:3600,value:m.siliconflow_asr_chunk_duration_seconds??1800,onChange:e=>B({...m,siliconflow_asr_chunk_duration_seconds:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`长音频按此时长切片,默认 1800 秒(30 分钟)。API 单次最长 60 分钟。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`siliconflow_asr_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`ASR 并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,max:8,value:m.siliconflow_asr_concurrency??2,onChange:e=>B({...m,siliconflow_asr_concurrency:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`同时发送的转写请求数,默认 2。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:gt,onClick:()=>void fa(),children:gt?`测试中...`:`测试 ASR 是否可用`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用当前表单中的 SiliconFlow Base URL、API Key 和 ASR 模型名发起一次临时转写测试,不会保存设置。`})]})]}):fi?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`multimodal_asr_base_url`?`is-highlighted`:``}`,ref:V(`multimodal_asr_base_url`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态 ASR Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.multimodal_asr_base_url,onChange:e=>B({...m,multimodal_asr_base_url:e.target.value}),placeholder:`https://api.example.com/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`支持 OpenAI 兼容的多模态 API 地址。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`multimodal_asr_api_key`?`is-highlighted`:``}`,ref:V(`multimodal_asr_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态 ASR API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.multimodal_asr_api_key,onFocus:rJ,onChange:e=>B({...m,multimodal_asr_api_key:e.target.value}),placeholder:`sk-...`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`multimodal_asr_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态 ASR 模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.multimodal_asr_model,onChange:e=>B({...m,multimodal_asr_model:e.target.value}),placeholder:`mimo-v2-omni`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用支持音频输入的多模态模型进行语音转文字。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`multimodal_asr_chunk_duration_seconds`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态切片时长(秒)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:30,max:600,value:m.multimodal_asr_chunk_duration_seconds??180,onChange:e=>B({...m,multimodal_asr_chunk_duration_seconds:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`长音频自动切片时每段的秒数,默认 180 秒(3 分钟)。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`multimodal_asr_max_retries`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态切片重试次数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:0,max:10,value:m.multimodal_asr_max_retries??5,onChange:e=>B({...m,multimodal_asr_max_retries:Number(e.target.value)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`每段切片返回空时最多重试几次,默认 5 次。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:gt,onClick:()=>void fa(),children:gt?`测试中...`:`测试 ASR 是否可用`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用当前表单中的多模态配置发起一次临时转写测试,不会保存设置。`})]})]}):pi?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`FunASR 模型`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_model,onChange:e=>B({...m,funasr_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:`paraformer-zh`,children:`paraformer-zh(中文通用,推荐)`}),(0,R.jsx)(`option`,{value:`iic/SenseVoiceSmall`,children:`SenseVoice-Small(多语言)`}),(0,R.jsx)(`option`,{value:`iic/speech_seaco_paraformer_large_asr_nat-zh-cn-16k-common-vocab8404-pytorch`,children:`SEACO Paraformer(高级,带时间戳)`}),(0,R.jsx)(`option`,{value:`FunAudioLLM/Fun-ASR-Nano-2512`,children:`Fun-ASR-Nano(轻量级)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择 FunASR 语音识别模型`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_device`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`运行设备`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_device,onChange:e=>B({...m,funasr_device:e.target.value}),children:[(0,R.jsx)(`option`,{value:`cpu`,children:`CPU`}),(0,R.jsx)(`option`,{value:`cuda`,children:`GPU (CUDA)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择推理设备,GPU 需要 CUDA 支持`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_vad_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`语音活动检测 (VAD)`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_vad_model,onChange:e=>B({...m,funasr_vad_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:``,children:`关闭`}),(0,R.jsx)(`option`,{value:`fsmn-vad`,children:`开启(fsmn-vad)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`启用语音活动检测以提高识别准确度`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_punc_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动标点`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_punc_model,onChange:e=>B({...m,funasr_punc_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:``,children:`关闭`}),(0,R.jsx)(`option`,{value:`ct-punc`,children:`开启(ct-punc)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`自动添加标点符号`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_spk_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`说话人识别`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_spk_model,onChange:e=>B({...m,funasr_spk_model:e.target.value}),children:[(0,R.jsx)(`option`,{value:``,children:`关闭`}),(0,R.jsx)(`option`,{value:`cam++`,children:`开启(cam++)`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`识别不同说话人`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_hub`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型下载源`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.funasr_hub,onChange:e=>B({...m,funasr_hub:e.target.value}),children:[(0,R.jsx)(`option`,{value:`ms`,children:`ModelScope`}),(0,R.jsx)(`option`,{value:`hf`,children:`HuggingFace`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择模型下载源`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`funasr_hotword`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`热词(可选)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.funasr_hotword,onChange:e=>B({...m,funasr_hotword:e.target.value}),placeholder:`多个热词用空格分隔`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`提高特定词汇的识别准确度,多个热词用空格分隔`})]}),(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`可用性状态`}),(0,R.jsx)(`div`,{className:`settings-status-display`,children:ui?(0,R.jsxs)(`span`,{className:`text-success`,children:[`✅ FunASR 已安装`,g?.funasrVersion?`(${g.funasrVersion})`:``]}):(0,R.jsx)(`span`,{className:`text-danger`,children:`❌ FunASR 未安装 — 请前往「运行环境」板块安装`})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:ui?`FunASR 环境就绪,可直接使用。`:`FunASR 依赖需要单独安装。前往「运行环境」→「FunASR 运行环境」点击安装按钮,安装完成后会自动切换。`})]})]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`device_preference`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`推理设备`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:Xn(m.device_preference),onChange:e=>B({...m,device_preference:e.target.value}),children:[(0,R.jsx)(`option`,{value:`auto`,children:`自动选择`}),(0,R.jsx)(`option`,{value:`cuda`,children:`GPU (CUDA)`}),(0,R.jsx)(`option`,{value:`cpu`,children:`CPU`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`选择推理设备,GPU 需要 CUDA 支持`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型模式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.model_mode,onChange:e=>B({...m,model_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`fixed`,children:`固定模型`}),(0,R.jsx)(`option`,{value:`auto`,children:`自动选择`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`自动模式会根据设备选择最优模型`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`fixed_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`固定模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.fixed_model,onChange:e=>B({...m,fixed_model:e.target.value}),placeholder:`tiny / base / small / medium / large-v3`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`Whisper 模型名称,小模型速度快但精度低`})]})]})]})]}),Pt===`generation`&&(0,R.jsxs)(`section`,{className:`settings-category-section generation-settings-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`摘要生成`}),(0,R.jsx)(`p`,{children:`按"基础生成、模型接入、自动产物、图文截图、长视频切块"分层管理,日常开关留在页面,密钥和模型细节放进悬浮窗。`})]}),(0,R.jsxs)(`div`,{className:`generation-settings-tree`,children:[(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`01`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`基础生成`}),(0,R.jsx)(`p`,{children:`控制摘要是否使用 LLM、输出语言和失败重试。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用 LLM 摘要`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,ref:V(`llm_enabled`),value:m.llm_enabled?`true`:`false`,onChange:e=>B({...m,llm_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用大语言模型生成更高质量的视频摘要。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要模式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.summary_mode,onChange:e=>B({...m,summary_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`llm`,children:`LLM 智能摘要`}),(0,R.jsx)(`option`,{value:`extract`,children:`仅转写`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`language`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`输出语言`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.language,onChange:e=>B({...m,language:e.target.value}),children:[(0,R.jsx)(`option`,{value:`zh`,children:`中文`}),(0,R.jsx)(`option`,{value:`en`,children:`English`}),(0,R.jsx)(`option`,{value:`ja`,children:`日本語`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_retry_count`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`重试次数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_retry_count,onChange:e=>B({...m,summary_chunk_retry_count:sJ(e.target.value,2)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`摘要 API 调用失败时的重试次数。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`02`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`模型接入`}),(0,R.jsx)(`p`,{children:`主摘要模型和视觉理解模型只展示状态,具体地址、密钥和测试放入悬浮窗。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-model-summary-grid`,children:[(0,R.jsxs)(`article`,{className:`settings-model-card settings-focus-target ${Rt===`llm_base_url`||Rt===`llm_api_key`||Rt===`llm_model`?`is-highlighted`:``}`,ref:e=>{V(`llm_base_url`)(e),V(`llm_api_key`)(e),V(`llm_model`)(e)},children:[(0,R.jsxs)(`div`,{className:`settings-model-card-top`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-model-kicker`,children:`主摘要模型`}),(0,R.jsx)(`strong`,{children:Yr})]}),(0,R.jsx)(`span`,{className:`settings-status-pill ${Jr}`,title:Wr.message||void 0,children:Kr})]}),(0,R.jsxs)(`dl`,{className:`settings-model-meta`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Provider`}),(0,R.jsx)(`dd`,{children:m.llm_provider||`openai-compatible`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Model`}),(0,R.jsx)(`dd`,{children:m.llm_model||`未填写`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Base URL`}),(0,R.jsx)(`dd`,{children:m.llm_base_url||`未填写`})]})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ut(`main`),children:`编辑与测试`})]}),(0,R.jsxs)(`article`,{className:`settings-model-card settings-focus-target ${Rt===`visual_multimodal_enabled`?`is-highlighted`:``}`,ref:V(`visual_multimodal_enabled`),children:[(0,R.jsxs)(`div`,{className:`settings-model-card-top`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-model-kicker`,children:`视觉理解模型`}),(0,R.jsx)(`strong`,{children:Qr})]}),(0,R.jsx)(`span`,{className:`settings-status-pill ${Zr}`,title:Gr.message||void 0,children:Xr})]}),(0,R.jsxs)(`dl`,{className:`settings-model-meta`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`来源`}),(0,R.jsx)(`dd`,{children:m.visual_evidence_base_url||m.visual_evidence_model||tJ(m.visual_evidence_api_key,m.visual_evidence_api_key_configured)?`独立配置`:`跟随主 LLM`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Model`}),(0,R.jsx)(`dd`,{children:m.visual_evidence_model||m.llm_model||`未填写`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`dt`,{children:`Base URL`}),(0,R.jsx)(`dd`,{children:m.visual_evidence_base_url||m.llm_base_url||`未填写`})]})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ut(`visual`),children:`编辑与测试`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`03`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`自动产物`}),(0,R.jsx)(`p`,{children:`摘要完成后是否自动追加导图和图文笔记。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-visual-note-presets`,"aria-label":`知识笔记预设`,children:[(0,R.jsxs)(`button`,{type:`button`,className:`settings-visual-note-preset ${$r===`text`?`is-active`:``}`,onClick:()=>Gi(`text`),children:[(0,R.jsx)(`strong`,{children:`纯文本笔记`}),(0,R.jsx)(`span`,{children:`只生成文本知识笔记。`})]}),(0,R.jsxs)(`button`,{type:`button`,className:`settings-visual-note-preset ${$r===`visual`?`is-active`:``}`,onClick:()=>Gi(`visual`),children:[(0,R.jsx)(`strong`,{children:`无多模态的图文笔记`}),(0,R.jsx)(`span`,{children:`抽帧并按文本语义插图。`})]}),(0,R.jsxs)(`button`,{type:`button`,className:`settings-visual-note-preset ${$r===`multimodal`?`is-active`:``}`,onClick:()=>Gi(`multimodal`),children:[(0,R.jsx)(`strong`,{children:`多模态理解的图文笔记`}),(0,R.jsx)(`span`,{children:`抽帧并调用 VLM 理解画面。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`auto_generate_mindmap`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动生成思维导图`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.auto_generate_mindmap?`true`:`false`,onChange:e=>B({...m,auto_generate_mindmap:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`关闭后仍可在详情页手动生成。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`prompt_router_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Prompt 路由模式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.prompt_router_mode||`confirm`,onChange:e=>B({...m,prompt_router_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`confirm`,children:`确认后使用推荐`}),(0,R.jsx)(`option`,{value:`auto`,children:`自动套用推荐`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`首页会根据标题推荐摘要 Prompt。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_note_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`知识笔记形式`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_note_mode||`text`,onChange:e=>{let t=e.target.value;B({...m,visual_note_mode:t,visual_evidence_enabled:t!==`text`,visual_evidence_use_llm:t===`vlm_integrated`,visual_multimodal_enabled:t===`vlm_integrated`})},children:[(0,R.jsx)(`option`,{value:`text`,children:`纯文本笔记`}),(0,R.jsx)(`option`,{value:`frame_insert`,children:`插图笔记`}),(0,R.jsx)(`option`,{value:`vlm_integrated`,children:`理解型图文笔记`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`纯文本不抽帧;理解型图文会调用 VLM 解析图片内容。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_evidence_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动生成图文笔记`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_evidence_enabled?`true`:`false`,disabled:(m.visual_note_mode||`text`)===`text`,onChange:e=>B({...m,visual_evidence_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`摘要完成后在独立队列生成图文版。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`多模态理解`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_multimodal_enabled?`true`:`false`,disabled:(m.visual_note_mode||`text`)!==`vlm_integrated`,onChange:e=>B({...m,visual_multimodal_enabled:e.target.value===`true`,visual_evidence_use_llm:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭,仅按文本语义插图`}),(0,R.jsx)(`option`,{value:`true`,children:`开启,调用 VLM 理解画面`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`开启后会把压缩识别图送入视觉模型。`})]})]})]}),(m.visual_note_mode||`text`)===`text`?null:(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`04`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`图文截图`}),(0,R.jsx)(`p`,{children:`只影响图文笔记抽帧和图片质量,不影响文本总结。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_download_resolution`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`下载分辨率`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_download_resolution||`720p`,onChange:e=>B({...m,visual_download_resolution:e.target.value}),children:[(0,R.jsx)(`option`,{value:`auto`,children:`自动`}),(0,R.jsx)(`option`,{value:`360p`,children:`360p`}),(0,R.jsx)(`option`,{value:`480p`,children:`480p`}),(0,R.jsx)(`option`,{value:`720p`,children:`720p`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`只影响图文笔记抽帧视频。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`最多截图数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,max:30,value:m.visual_evidence_max_frames,onChange:e=>B({...m,visual_evidence_max_frames:sJ(e.target.value,12)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`后端限制在 1-30 张。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`截图最小间隔(秒)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:10,value:m.visual_evidence_frame_interval_seconds,onChange:e=>B({...m,visual_evidence_frame_interval_seconds:sJ(e.target.value,10)})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`笔记图片宽度`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:320,max:1600,value:m.visual_evidence_frame_width,onChange:e=>B({...m,visual_evidence_frame_width:sJ(e.target.value,960)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制最终图文笔记中的截图宽度上限。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`识别图质量`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,max:100,value:m.visual_evidence_image_quality,onChange:e=>B({...m,visual_evidence_image_quality:sJ(e.target.value,85)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`仅用于 VLM 识别压缩图。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:(m.visual_note_mode||`text`)===`text`?`04`:`05`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`Twelve Labs Pegasus 视频理解`}),(0,R.jsx)(`p`,{children:`可选。仅对本地视频生效,直接"看"画面生成理解摘要并写入知识笔记。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`twelvelabs_summary_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用 Pegasus 视频摘要`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.twelvelabs_summary_enabled?`true`:`false`,onChange:e=>B({...m,twelvelabs_summary_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`仅本地视频生效,不影响在线视频摘要流程。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Twelve Labs API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.twelvelabs_api_key||``,placeholder:`tlk_...`,autoComplete:`off`,onChange:e=>B({...m,twelvelabs_api_key:e.target.value,twelvelabs_api_key_configured:!1})}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可在 `,(0,R.jsx)(`a`,{href:`https://twelvelabs.io`,target:`_blank`,rel:`noreferrer`,children:`twelvelabs.io`}),` 免费申请。`]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Pegasus 模型`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`text`,value:m.twelvelabs_model||`pegasus1.5`,placeholder:`pegasus1.5`,onChange:e=>B({...m,twelvelabs_model:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`text`,value:m.twelvelabs_base_url||`https://api.twelvelabs.io/v1.3`,placeholder:`https://api.twelvelabs.io/v1.3`,onChange:e=>B({...m,twelvelabs_base_url:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Pegasus 提示词(留空用默认)`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:4,value:m.twelvelabs_prompt||``,placeholder:`留空则使用内置默认提示词`,onChange:e=>B({...m,twelvelabs_prompt:e.target.value})})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:(m.visual_note_mode||`text`)===`text`?`05`:`06`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`长视频切块`}),(0,R.jsx)(`p`,{children:`控制长视频拆分摘要的连续性和单块长度。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_target_chars`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`分块目标字符数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_target_chars,onChange:e=>B({...m,summary_chunk_target_chars:sJ(e.target.value,2200)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`LLM 处理时分块的目标字符数。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_overlap_segments`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`分块重叠段数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_overlap_segments,onChange:e=>B({...m,summary_chunk_overlap_segments:sJ(e.target.value,2)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`分块之间保留的重叠段落。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-alert info`,children:[(0,R.jsx)(`strong`,{children:`分块并发在性能页调整`}),(0,R.jsx)(`span`,{children:`如果需要控制单个任务内部同时请求的摘要块数量,请前往"性能与资源"。`})]})]})]})]})]}),Pt===`knowledge`&&(0,R.jsxs)(`section`,{className:`settings-category-section generation-settings-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`知识库与问答`}),(0,R.jsx)(`p`,{children:`知识库默认关闭,依赖按需安装到当前运行环境。按"基础开关、向量模型、LLM 配置"分层管理。`})]}),(0,R.jsxs)(`div`,{className:`generation-settings-tree`,children:[(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`01`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`基础开关`}),(0,R.jsx)(`p`,{children:`控制知识库启停、索引策略和依赖安装。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用知识库`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_enabled?`true`:`false`,onChange:e=>B({...m,knowledge_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`关闭时不会自动构建索引;标签管理仍可使用。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动维护知识库索引`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_index_auto_rebuild||`disabled`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_index_auto_rebuild:e.target.value}),children:[(0,R.jsx)(`option`,{value:`disabled`,children:`关闭自动维护`}),(0,R.jsx)(`option`,{value:`on_task_completed`,children:`视频生成结束后更新索引`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`开启知识库并安装依赖后,才会在任务完成时自动刷新索引。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`02`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`向量模型`}),(0,R.jsx)(`p`,{children:`选择 Embedding 模型的下载源和模型名。国内用户建议使用 ModelScope 源或 HuggingFace 镜像。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_embedding_provider`?`is-highlighted`:``}`,ref:V(`knowledge_embedding_provider`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型来源`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_embedding_provider||`local_huggingface`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_embedding_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`siliconflow`,children:`硅基流动在线 API`}),(0,R.jsx)(`option`,{value:`local_huggingface`,children:`本地 HuggingFace`}),(0,R.jsx)(`option`,{value:`local_modelscope`,children:`本地 ModelScope`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:m.knowledge_embedding_provider===`siliconflow`?`使用在线 API,无需本地向量模型和 GPU;索引存储仍需要 chromadb。`:`向量模型从哪个源下载和加载。`})]}),m.knowledge_embedding_provider===`siliconflow`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`siliconflow_embedding_api_key`?`is-highlighted`:``}`,ref:V(`siliconflow_embedding_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.siliconflow_embedding_api_key||``,disabled:!m.knowledge_enabled,onFocus:rJ,onChange:e=>B({...m,siliconflow_embedding_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(qq,{purpose:`embedding`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_embedding_base_url||Qq,disabled:!m.knowledge_enabled,onChange:e=>B({...m,siliconflow_embedding_base_url:e.target.value}),placeholder:`https://api.siliconflow.cn/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`硅基流动 API 端点,通常不需要修改。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.siliconflow_embedding_model||$q,disabled:!m.knowledge_enabled,onChange:e=>B({...m,siliconflow_embedding_model:e.target.value}),placeholder:`BAAI/bge-large-zh-v1.5`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`推荐使用 BAAI/bge-large-zh-v1.5 或 Qwen/Qwen3-Embedding-8B。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,style:{gridColumn:`1 / -1`},children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:He||!m.knowledge_enabled||!Si,onClick:()=>void ra(),children:He?`测试中...`:`测试向量模型`}),Je?(0,R.jsx)(`span`,{className:`settings-status-pill success`,children:`API 可用`}):Lr?(0,R.jsx)(`span`,{className:`settings-status-pill warning`,children:`待测试`}):null]}),We?(0,R.jsx)(`div`,{className:`settings-inline-alert ${Je?`success`:We.includes(`失败`)||We.includes(`未配置`)?`warning`:`info`}`,children:(0,R.jsx)(`span`,{children:We})}):null,Ke?(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:6,readOnly:!0,value:Ke}):null]}):m.knowledge_embedding_provider===`online`?null:(0,R.jsxs)(R.Fragment,{children:[Object.keys(Xe).length>0?(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`推荐模型`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_embedding_model&&Xe[m.knowledge_embedding_model]?m.knowledge_embedding_model:`__custom__`,disabled:!m.knowledge_enabled,onChange:e=>{e.target.value===`__custom__`?B({...m,knowledge_embedding_model:``}):B({...m,knowledge_embedding_model:e.target.value})},children:[Object.entries(Xe).map(([e,t])=>(0,R.jsx)(`option`,{value:e,children:t},e)),(0,R.jsx)(`option`,{value:`__custom__`,children:`自定义模型名...`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`从推荐列表中选择,或选"自定义模型名"手动输入。`})]}):null,(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_embedding_model`?`is-highlighted`:``}`,ref:V(`knowledge_embedding_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.knowledge_embedding_model,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_embedding_model:e.target.value}),placeholder:`BAAI/bge-small-zh-v1.5`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:m.knowledge_embedding_provider===`local_huggingface`?`HuggingFace 上的模型 ID,如 BAAI/bge-small-zh-v1.5。`:`ModelScope 上的模型 ID,如 BAAI/bge-small-zh-v1.5。`})]}),m.knowledge_embedding_provider===`local_huggingface`?(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`hf_endpoint`?`is-highlighted`:``}`,ref:V(`hf_endpoint`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`HuggingFace 镜像地址`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.hf_endpoint,disabled:!m.knowledge_enabled,onChange:e=>B({...m,hf_endpoint:e.target.value}),placeholder:`留空使用官方源,或填 https://hf-mirror.com`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`国内用户建议填写 https://hf-mirror.com 加速下载。`})]}):null,(0,R.jsxs)(`div`,{className:`settings-inline-actions`,style:{gridColumn:`1 / -1`},children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:Be||!m.knowledge_enabled,onClick:()=>void na(),children:Be?`下载中...`:`下载模型`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:He||Be||!m.knowledge_enabled,onClick:()=>void ra(),children:He?`验证中...`:`验证模型`}),Je?(0,R.jsx)(`span`,{className:`settings-status-pill success`,children:`已就绪`}):null]}),We?(0,R.jsx)(`div`,{className:`settings-inline-alert ${Je?`success`:We.includes(`失败`)?`warning`:`info`}`,children:(0,R.jsx)(`span`,{children:We})}):null,Ke?(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:10,readOnly:!0,value:Ke}):null]})]})]}),m.knowledge_embedding_provider===`siliconflow`?null:(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:`03`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`运行依赖`}),(0,R.jsx)(`p`,{children:`知识库依赖(chromadb、sentence-transformers)需要到"运行环境"页面统一安装管理。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`div`,{className:`knowledge-deps-status-card ${yi?`status-ready`:`status-missing`}`,children:[(0,R.jsx)(`div`,{className:`knowledge-deps-status-icon`,children:yi?`✓`:`⚠`}),(0,R.jsxs)(`div`,{className:`knowledge-deps-status-content`,children:[(0,R.jsx)(`strong`,{className:`knowledge-deps-status-title`,children:yi?`依赖已就绪`:Ci?`依赖损坏`:`缺失 ${Ei.length} 个依赖`}),(0,R.jsx)(`p`,{className:`knowledge-deps-status-desc`,children:yi?`chromadb${g?.chromadbVersion?` ${g.chromadbVersion}`:``} 与 sentence-transformers${g?.sentenceTransformersVersion?` ${g.sentenceTransformersVersion}`:``} 已在当前运行环境可用。`:Ci?`部分依赖包已安装但无法正常导入,需要重新安装。`:`需要安装:${Ei.join(`、`)||Ti}。`})]})]}),(0,R.jsxs)(`div`,{className:`knowledge-deps-navigate`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,onClick:()=>{Ft(`runtime`),setTimeout(()=>{document.querySelector(`[data-focus-key="knowledge_runtime"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})},100)},children:`前往运行环境管理`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`在运行环境页面可以查看完整依赖树、安装/卸载单个依赖包、查看安装日志。`})]})]})]}),(0,R.jsxs)(`section`,{className:`settings-tree-panel`,children:[(0,R.jsxs)(`header`,{className:`settings-tree-panel-header`,children:[(0,R.jsx)(`span`,{className:`settings-tree-index`,children:m.knowledge_embedding_provider===`siliconflow`?`03`:`04`}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`h3`,{children:`知识库 LLM`}),(0,R.jsx)(`p`,{children:`自动打标和知识库问答可以跟随主 LLM,也可以使用独立配置。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-tree-grid`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_llm_mode`?`is-highlighted`:``}`,ref:V(`knowledge_llm_mode`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`LLM 来源`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_llm_mode||`same_as_main`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_mode:e.target.value}),children:[(0,R.jsx)(`option`,{value:`same_as_main`,children:`跟随主 LLM`}),(0,R.jsx)(`option`,{value:`custom`,children:`使用独立配置`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`"跟随主 LLM" 会直接复用摘要 LLM 的 Base URL、API Key 与模型名。`})]}),ei?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`knowledge_llm_enabled`?`is-highlighted`:``}`,ref:V(`knowledge_llm_enabled`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`启用知识库 LLM`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_llm_enabled?`true`:`false`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_enabled:e.target.value===`true`}),children:[(0,R.jsx)(`option`,{value:`false`,children:`关闭`}),(0,R.jsx)(`option`,{value:`true`,children:`开启`})]})]}),m.knowledge_llm_enabled?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_provider`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`LLM 提供商`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.knowledge_llm_provider||`openai-compatible`,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI Compatible`}),(0,R.jsx)(`option`,{value:`openai`,children:`OpenAI`}),(0,R.jsx)(`option`,{value:`anthropic`,children:`Anthropic`}),(0,R.jsx)(`option`,{value:`custom`,children:`自建端点`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_base_url`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.knowledge_llm_base_url,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_base_url:e.target.value}),placeholder:`https://api.openai.com/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`知识库问答与自动打标 LLM API 的基础 URL 地址。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_api_key`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.knowledge_llm_api_key,disabled:!m.knowledge_enabled,onFocus:rJ,onChange:e=>B({...m,knowledge_llm_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`知识库 LLM 服务的 API 密钥。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_llm_model`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.knowledge_llm_model,disabled:!m.knowledge_enabled,onChange:e=>B({...m,knowledge_llm_model:e.target.value}),placeholder:`gpt-4o-mini / claude-3-haiku`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`要用于知识库问答和自动打标的 LLM 模型名称。`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:St||!m.knowledge_enabled,onClick:()=>void ca(),children:St?`测试中...`:`测试知识库 LLM`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用当前表单中的 Base URL、API Key 和模型名临时请求一次,并校验是否能返回合法 JSON,不会保存设置。`})]})]}):null]}):(0,R.jsxs)(`div`,{className:`settings-inline-alert ${ti?`success`:`warning`}`,children:[(0,R.jsx)(`strong`,{children:ti?`知识库当前跟随主 LLM`:`知识库当前跟随主 LLM,但主 LLM 还未补全`}),(0,R.jsx)(`span`,{children:ti?`自动打标和问答会直接复用主 LLM 配置。`:`请先启用主 LLM,并补全 API Key、Base URL 与模型名,或切换为独立配置。`})]})]})]})]})]}),Pt===`prompts`&&(0,R.jsxs)(`section`,{className:`settings-category-section settings-prompts-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`提示词`}),(0,R.jsx)(`p`,{children:`这里属于高级个性化区域。想改变知识笔记风格时再调整,日常使用保持默认即可。`})]}),(0,R.jsxs)(`div`,{className:`settings-prompt-scope-alert`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-scope-kicker`,children:`生效范围`}),(0,R.jsx)(`p`,{children:`首页选择的 Prompt 预设只影响摘要生成;知识笔记和图文笔记使用下方全局模板。恢复默认或修改模板后,需要点击左侧"保存设置"才会生效。`})]}),lr&&(0,R.jsxs)(`div`,{className:`settings-prompt-global-sticky`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-toolbar-title`,children:[`已展开 `,nr.size,` 项`]}),(0,R.jsx)(`button`,{className:`settings-prompt-inline-action`,type:`button`,onClick:e=>{e.preventDefault(),dr()},children:`收起全部`})]}),(0,R.jsxs)(`div`,{className:`settings-prompt-list`,children:[(0,R.jsxs)(`details`,{className:`settings-prompt-collapse`,ref:e=>{nn.current.summary=e},onToggle:e=>pr(`summary`,e),children:[(0,R.jsxs)(`summary`,{className:`settings-prompt-collapse-summary`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`摘要 Prompt`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`控制视频摘要的角色、结构和输出格式。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-chip accent`,children:`核心`}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_system_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要 System Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:5,value:m.summary_system_prompt||``,onChange:e=>B({...m,summary_system_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Hi(`system`),children:`恢复默认`}),On?.summary_system_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制视频摘要生成时的角色、风格和整体约束。`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_user_prompt_template`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要 User Template`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:14,value:m.summary_user_prompt_template||``,onChange:e=>B({...m,summary_user_prompt_template:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Hi(`template`),children:`恢复默认`}),On?.summary_user_prompt_template!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{transcript}`,`、`,`{segments_json}`,`。生成 JSON 包含 title/overview/bulletPoints/chapters/chapterGroups。`]})]})]})]})]}),(0,R.jsxs)(`div`,{className:`settings-prompt-collapse settings-focus-target ${En?` open`:``}`,ref:V(`prompt_presets_library`),children:[(0,R.jsxs)(`div`,{className:`settings-prompt-collapse-summary`,role:`button`,tabIndex:0,"aria-expanded":En,onClick:I,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),I())},children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`Prompt 预设库`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`管理首页摘要 Prompt 下拉框和自动推荐候选。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-chip`,children:[`内置 `,Kn]}),(0,R.jsxs)(`span`,{className:`settings-prompt-chip muted`,children:[`隐藏 `,qn]}),(0,R.jsxs)(`span`,{className:`settings-prompt-chip success`,children:[`新增 `,Jn]}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),En&&(0,R.jsxs)(`div`,{className:`settings-form-group`,style:{position:`relative`},children:[(0,R.jsxs)(`div`,{className:`settings-preset-section-note`,children:[(0,R.jsx)(`strong`,{children:`摘要预设`}),(0,R.jsx)(`span`,{children:`用于首页 Prompt 下拉框和自动推荐,只替换摘要 System Prompt / User Template。内置预设可查看或隐藏,新增预设可编辑或删除。`})]}),Qn.length?(0,R.jsxs)(`div`,{className:`settings-hidden-preset-list`,children:[(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`已隐藏内置预设`}),(0,R.jsx)(`div`,{className:`settings-hidden-preset-actions`,children:Qn.map(e=>(0,R.jsxs)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>er(e.id,!1),children:[`恢复 `,e.name]},e.id))})]}):null,fn?(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`加载中...`}):cn.length===0?(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`暂无预设`}):(0,R.jsx)(R.Fragment,{children:Yn.map(tr)}),gn&&(0,R.jsx)(`div`,{className:`settings-preset-card new`,children:(0,R.jsxs)(`div`,{className:`settings-preset-edit-body`,children:[(0,R.jsx)(`h4`,{children:`新建预设`}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`名称 *`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.name,onChange:e=>yn({...vn,name:e.target.value}),placeholder:`预设名称(用作 ID)`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`描述`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.description||``,onChange:e=>yn({...vn,description:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`分类`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.category||``,onChange:e=>yn({...vn,category:e.target.value}),placeholder:`例如: 教程、会议、娱乐`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`自动匹配关键词(逗号分隔)`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:vn.auto_match_keywords?.join(`、`)||``,onChange:e=>yn({...vn,auto_match_keywords:e.target.value.split(/[,,、]/).map(e=>e.trim()).filter(Boolean)}),placeholder:`例如: 教程、教学、入门`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`System Prompt *`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:4,value:vn.system_prompt,onChange:e=>yn({...vn,system_prompt:e.target.value})})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-preset-field`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`User Template *`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:10,value:vn.user_prompt_template,onChange:e=>yn({...vn,user_prompt_template:e.target.value})})]}),(0,R.jsxs)(`div`,{className:`settings-preset-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:bn,onClick:Un,children:bn?`创建中...`:`创建预设`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Bn,children:`取消`})]})]})}),Sn&&(0,R.jsx)(`p`,{className:`settings-input-caption`,style:{marginTop:8,color:Sn.includes(`失败`)?`var(--danger)`:`var(--success)`},children:Sn}),!gn&&!fn&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:zn,style:{marginTop:12},children:`+ 新建预设`})]})]}),(0,R.jsxs)(`details`,{className:`settings-prompt-collapse`,ref:e=>{nn.current.knowledge=e},onToggle:e=>pr(`knowledge`,e),children:[(0,R.jsxs)(`summary`,{className:`settings-prompt-collapse-summary`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`知识笔记 Prompt`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`控制知识笔记的整理风格、Markdown 结构和变量使用。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-chip`,children:`全局模板`}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_note_system_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`知识笔记 System Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:5,value:m.knowledge_note_system_prompt||``,onChange:e=>B({...m,knowledge_note_system_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ui(`system`),children:`恢复默认`}),On?.knowledge_note_system_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制知识笔记生成时的角色、风格和整体约束。`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`knowledge_note_user_prompt_template`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`知识笔记 User Template`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:14,value:m.knowledge_note_user_prompt_template||``,onChange:e=>B({...m,knowledge_note_user_prompt_template:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Ui(`template`),children:`恢复默认`}),On?.knowledge_note_user_prompt_template!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{transcript_excerpt}`,`、`,`{segments_excerpt}`,`、`,`{summary_json}`,`。`]})]})]}),(0,R.jsxs)(`div`,{className:`settings-guide-card`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`strong`,{children:`想调整知识笔记样式?`}),(0,R.jsx)(`span`,{children:`查看变量、默认结构和常见改法,避免破坏 JSON 输出格式。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Vt(!0),children:`打开教程`})]})]})]}),(0,R.jsxs)(`details`,{className:`settings-prompt-collapse`,ref:e=>{nn.current.visual=e},onToggle:e=>pr(`visual`,e),children:[(0,R.jsxs)(`summary`,{className:`settings-prompt-collapse-summary`,children:[(0,R.jsxs)(`span`,{className:`settings-prompt-summary-copy`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-summary-title`,children:`图文笔记 Prompt`}),(0,R.jsx)(`span`,{className:`settings-prompt-summary-desc`,children:`控制关键帧选择、画面理解和图文笔记整合。`})]}),(0,R.jsxs)(`span`,{className:`settings-prompt-summary-meta`,children:[(0,R.jsx)(`span`,{className:`settings-prompt-chip info`,children:`VLM`}),(0,R.jsx)(`span`,{className:`settings-prompt-open-label`,children:`展开`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_note_system_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`图文笔记 System Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:5,value:m.visual_note_system_prompt||``,onChange:e=>B({...m,visual_note_system_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`system`),children:`恢复默认`}),On?.visual_note_system_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`控制理解型图文笔记如何把图片解析整合进正文。`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_frame_planning_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`捕获帧规划 Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:10,value:m.visual_frame_planning_prompt||``,onChange:e=>B({...m,visual_frame_planning_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`planning`),children:`恢复默认`}),On?.visual_frame_planning_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{mode}`,`、`,`{summary_json}`,`、`,`{knowledge_note_markdown}`,`、`,`{segments_excerpt}`,`、`,`{max_frames}`,`。`]})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_vlm_prompt`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`画面理解 Prompt`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:10,value:m.visual_vlm_prompt||``,onChange:e=>B({...m,visual_vlm_prompt:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`vlm`),children:`恢复默认`}),On?.visual_vlm_prompt!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{timestamp}`,`、`,`{context}`,`、`,`{timeline_hint}`,`、`,`{knowledge_note_markdown}`,`。`]})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`visual_note_user_prompt_template`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`图文笔记 User Template`}),(0,R.jsx)(`textarea`,{className:`textarea-field`,rows:12,value:m.visual_note_user_prompt_template||``,onChange:e=>B({...m,visual_note_user_prompt_template:e.target.value})}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>Wi(`template`),children:`恢复默认`}),On?.visual_note_user_prompt_template!==void 0&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:Vi,children:`回退设置`}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`可用变量:`,`{title}`,`、`,`{knowledge_note_markdown}`,`、`,`{visual_observations_json}`,`。`]})]})]})]})]})]})]}),Pt===`performance`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`性能调优`}),(0,R.jsx)(`p`,{children:`控制任务级并发与单任务内部分块并发,减少本地资源争抢和云端限流压力。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`task_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`任务并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.task_concurrency,onChange:e=>B({...m,task_concurrency:sJ(e.target.value,mi)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`影响下载、转写、摘要的整体链路吞吐;云 API 可能存在并发限流,建议按当前环境推荐值设置。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`mindmap_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`导图并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.mindmap_concurrency,onChange:e=>B({...m,mindmap_concurrency:sJ(e.target.value,1)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`影响摘要完成后的导图生成吞吐,不会占用摘要任务的并发槽位;建议保持 1。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`summary_chunk_concurrency`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`摘要分块并发数`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`number`,min:1,value:m.summary_chunk_concurrency,onChange:e=>B({...m,summary_chunk_concurrency:sJ(e.target.value,2)})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`仅控制单个摘要任务内部同时请求的分块数量,不等同于任务并发数。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`当前建议`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:hi})]}),(0,R.jsxs)(`div`,{className:`settings-input-group settings-performance-tasklist-entry`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`当前任务队列`}),(0,R.jsxs)(`div`,{className:`settings-inline-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>qt(!0),children:`查看 tasklist`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`使用悬浮窗快速查看最近任务,避免占用主要设置区域。`})]})]})]})]}),Pt===`performance`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`资源策略`}),(0,R.jsx)(`p`,{children:`根据机器和任务规模调整 CUDA 版本、运行环境通道和缓存策略。`})]}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`cuda_variant`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`CUDA 变体`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.cuda_variant,onChange:e=>B({...m,cuda_variant:e.target.value}),children:[(0,R.jsx)(`option`,{value:`cu128`,children:`CUDA 12.8`}),(0,R.jsx)(`option`,{value:`cu126`,children:`CUDA 12.6`}),(0,R.jsx)(`option`,{value:`cu124`,children:`CUDA 12.4`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`PyTorch CUDA 版本`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,ref:V(`runtime_channel`),children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`运行环境通道`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.runtime_channel,onChange:e=>B({...m,runtime_channel:e.target.value}),children:[(0,R.jsx)(`option`,{value:`base`,children:`基础版`}),(0,R.jsx)(`option`,{value:`gpu-cu128`,children:`GPU CUDA12.8`}),(0,R.jsx)(`option`,{value:`gpu-cu126`,children:`GPU CUDA12.6`}),(0,R.jsx)(`option`,{value:`gpu-cu124`,children:`GPU CUDA12.4`})]})]})]})]}),Pt===`runtime`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`运行环境`}),(0,R.jsx)(`p`,{children:`环境检测信息、CUDA 配置和本地 ASR 安装。`})]}),(0,R.jsxs)(`div`,{className:`env-summary-grid settings-env-grid`,ref:V(`runtime_status`),children:[(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`推荐设备`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.recommendedDevice||`-`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`请求设备`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:Zn(m.device_preference)})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`生效设备`}),(0,R.jsx)(`strong`,{className:`metric-value ${(m.transcription_provider===`funasr`?Xn(m.funasr_device):Xn(m.whisper_device))===`cuda`?`text-success`:``}`,children:m.transcription_provider===`funasr`?Zn(m.funasr_device):Zn(m.whisper_device)})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`推荐模型`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.recommendedModel||`-`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`GPU 状态`}),(0,R.jsx)(`strong`,{className:`metric-value ${g?.cudaAvailable?`text-success`:``}`,children:g?.cudaAvailable?`已启用`:`未启用`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`GPU 名称`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.gpuName||`未检测到`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`Torch`}),(0,R.jsx)(`strong`,{className:`metric-value ${g?.torchInstalled?`text-success`:``}`,children:g?.torchInstalled?g?.torchVersion||`已安装`:`未安装`})]}),(0,R.jsxs)(`div`,{className:`metric-card`,children:[(0,R.jsx)(`span`,{className:`metric-label`,children:`Python`}),(0,R.jsx)(`strong`,{className:`metric-value`,children:g?.pythonVersion||`-`})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`CUDA 目标版本`}),(0,R.jsxs)(`div`,{className:`cuda-insight-grid`,children:[(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`目标运行环境`}),(0,R.jsx)(`span`,{className:`setting-value`,children:Er})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`当前运行环境`}),(0,R.jsx)(`span`,{className:`setting-value`,children:g?.runtimeChannel||m.runtime_channel||`base`})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`运行环境状态`}),(0,R.jsx)(`span`,{className:`setting-value`,children:g?.runtimeReady?`已就绪`:g?.runtimeError?`异常`:`检测中...`})]})]}),(0,R.jsx)(`span`,{className:`input-label`,children:`CUDA 目标版本`}),(0,R.jsxs)(`div`,{className:`settings-actions cuda-button-row`,children:[(0,R.jsxs)(`select`,{className:`select-field cuda-select-field`,value:m.cuda_variant,disabled:k,onChange:e=>B({...m,cuda_variant:e.target.value}),children:[(0,R.jsx)(`option`,{value:`cu128`,children:`CUDA 12.8`}),(0,R.jsx)(`option`,{value:`cu126`,children:`CUDA 12.6`}),(0,R.jsx)(`option`,{value:`cu124`,children:`CUDA 12.4`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:k,onClick:async()=>{try{E(`正在重新检测环境...`),_(await L.getEnvironment({runtimeChannel:m.runtime_channel,refresh:!0})),E(`环境检测完成`),i()}catch(e){E(e instanceof Error?e.message:`环境检测失败`)}},children:`重新检测`}),(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:k,onClick:async()=>{let e=`cuda-${Date.now()}`,t=null;try{A(!0),E(`正在安装 CUDA 支持...`),O(``),M(0),t=setInterval(async()=>{try{let n=await L.getInstallLog(e);n.log&&O(n.log),typeof n.progress==`number`&&M(n.progress),n.done&&t&&(clearInterval(t),t=null)}catch{}},1500);let n=await L.installCuda({cuda_variant:m.cuda_variant,installSessionId:e});t&&=(clearInterval(t),null),M(100);try{let t=await L.getInstallLog(e);t.log&&O(t.log)}catch{}let r=n.runtimeChannel||m.runtime_channel;A(!1),E(n.restartRequired?`CUDA 安装完成,请重启应用后切换到新的 GPU 运行环境`:`CUDA 安装完成`),h({...m,runtime_channel:r,cuda_variant:n.cudaVariant||m.cuda_variant}),y(!1),_(await L.getEnvironment({runtimeChannel:r,refresh:!0})),i()}catch(e){t&&=(clearInterval(t),null),A(!1),E(e instanceof Error?e.message:`CUDA 安装失败`)}},children:k?`安装中...`:`安装 CUDA 支持`})]}),k||T||D?(0,R.jsx)(`div`,{className:`settings-form-group`,children:(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`CUDA 安装输出`}),k&&j>0?(0,R.jsx)(`div`,{className:`progress-bar-simple`,style:{marginBottom:8},children:(0,R.jsx)(`div`,{className:`progress-fill-simple`,style:{width:`${j}%`}})}):null,(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:12,readOnly:!0,value:D||(k?`安装中...`:T)})]})}):null]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`运行环境更新检查`}),(0,R.jsxs)(`div`,{className:`settings-runtime-toolbar`,children:[(0,R.jsxs)(`span`,{className:`settings-inline-alert ${Ai.length>0?`warning`:`success`}`,children:[(0,R.jsx)(`strong`,{children:Ai.length>0?`有运行环境需要同步`:`运行环境基础版本一致`}),(0,R.jsx)(`span`,{children:Ai.length>0?`${Ai.map(e=>e.runtimeChannel).join(`、`)} 需要同步基础文件;同步会保留 CUDA / ASR / 知识库扩展包。`:`当前基础版本 ${et?.baseAppVersion||`-`},每 30 分钟自动检查一次。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:it,onClick:()=>void gr(),children:it?`检查中...`:`检查所有 runtime`}),Ai.length>0&&(0,R.jsx)(`button`,{className:`primary-button compact`,type:`button`,disabled:ot||it,onClick:()=>void _r(),children:ot?`同步中...`:`同步需要更新的 runtime`})]}),nt?(0,R.jsx)(`p`,{className:`settings-input-caption runtime-status-message`,children:nt}):null,(0,R.jsx)(`div`,{className:`runtime-channel-list`,role:`list`,children:(et?.channels||[]).map(e=>(0,R.jsxs)(`div`,{className:`runtime-channel-row`,role:`listitem`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`strong`,{children:e.runtimeChannel}),(0,R.jsx)(`span`,{children:e.ready?`已就绪`:e.exists?`缺少 Python`:`未创建`})]}),(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{children:e.appVersion||`-`}),(0,R.jsx)(`span`,{children:e.needsUpdate?`需同步`:e.exists?`最新`:`按需创建`})]})]},e.runtimeChannel))}),(0,R.jsxs)(`span`,{className:`settings-input-caption`,children:[`已启用国内镜像回退:`,ji,`。安装失败时会自动从官方源切换到国内镜像继续尝试。`]})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-list`,children:[(0,R.jsxs)(cJ,{title:`本地 ASR 运行环境`,status:vi?`已安装`:`未安装`,tone:vi?`installed`:`missing`,summary:vi?`faster-whisper ${g?.localAsrVersion||`已就绪`}`:`安装后可切换到本地 Whisper 转写`,open:An,onToggle:()=>jn(!An),focusKey:`local_asr_runtime`,highlighted:Rt===`local_asr_runtime`,sectionRef:V(`local_asr_runtime`),children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-intro`,children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-copy`,children:[(0,R.jsx)(`strong`,{children:vi?`本地 Whisper 已可用`:`安装到当前 runtime`}),(0,R.jsx)(`span`,{children:vi?`当前运行环境可直接使用本地语音识别;重新安装会保留同一运行环境通道并刷新依赖。`:`正式安装包默认不包含本地 ASR,安装完成后会自动切换到本地模式。`})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:ge,onClick:()=>void Zi(),children:ge?`安装中...`:vi?`重新安装本地 ASR`:`安装本地 ASR`}),fe?(0,R.jsx)(`span`,{className:`helper-chip runtime-operation-chip ${fe.includes(`失败`)?`status-error`:fe.includes(`安装`)||fe.includes(`已`)?`status-success`:`status-info`}`,children:fe}):null]})]}),(0,R.jsx)(Vq,{title:`本地 ASR 依赖`,items:Wq(g,`local`),runtimeChannel:m.runtime_channel,installKind:`local`,onStatusChange:ta}),me?(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title`,children:`安装输出`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:me})]}):null]}),(0,R.jsxs)(cJ,{title:`FunASR 运行环境`,status:ui?`已安装`:`未安装`,tone:ui?`installed`:`missing`,summary:ui?`funasr ${g?.funasrVersion||`已就绪`}`:`中文转写增强,包含 PyTorch 依赖`,open:Mn,onToggle:()=>Nn(!Mn),focusKey:`funasr_runtime`,highlighted:Rt===`funasr_runtime`,sectionRef:V(`funasr_runtime`),children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-intro`,children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-copy`,children:[(0,R.jsx)(`strong`,{children:ui?`FunASR 已可用`:`安装中文 ASR 增强包`}),(0,R.jsx)(`span`,{children:ui?`当前运行环境已经通过 FunASR 检测;重新安装会自动修复 torch、torchvision、torchaudio 等子依赖。`:`FunASR 是阿里开源语音识别引擎,依赖包含 PyTorch,安装体积较大,请耐心等待。`})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:Se,onClick:()=>void Qi(),children:Se?`安装中...`:ui?`重新安装 FunASR`:`安装 FunASR`}),ve?(0,R.jsx)(`span`,{className:`helper-chip runtime-operation-chip ${ve.includes(`失败`)?`status-error`:ve.includes(`已安装`)||ve.includes(`成功`)?`status-success`:`status-info`}`,children:ve}):null]})]}),(0,R.jsx)(Vq,{title:`FunASR 依赖`,items:Wq(g,`funasr`),runtimeChannel:m.runtime_channel,installKind:`funasr`,onStatusChange:ta}),be?(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title`,children:`安装输出`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:be})]}):null]}),(0,R.jsxs)(cJ,{title:`知识库运行环境`,status:Di,tone:Oi,summary:ki,open:Pn,onToggle:()=>Fn(!Pn),focusKey:`knowledge_runtime`,highlighted:Rt===`knowledge_runtime`,sectionRef:V(`knowledge_runtime`),children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-intro`,children:[(0,R.jsxs)(`div`,{className:`runtime-subsection-copy`,children:[(0,R.jsx)(`strong`,{children:yi?`知识库依赖已就绪`:Ci?`依赖需要修复`:`安装知识库依赖`}),(0,R.jsx)(`span`,{children:Rr?`当前 provider: siliconflow。本区域只负责本地知识库索引存储依赖,在线向量模型请在「知识库与问答」里测试。`:`当前 provider: ${m.knowledge_embedding_provider||`local_huggingface`}。本区域负责知识库索引存储和本地向量模型所需的 Python 依赖。`})]}),(0,R.jsxs)(`div`,{className:`runtime-subsection-actions`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:Ie,onClick:()=>void $i(),children:Ie?`安装中...`:yi||Ci?`重新安装知识库依赖`:`安装知识库依赖`}),Me?(0,R.jsx)(`span`,{className:`helper-chip runtime-operation-chip ${Me.includes(`成功`)||Me.includes(`就绪`)?`status-success`:Me.includes(`失败`)?`status-error`:`status-info`}`,children:Me}):null]})]}),Re&&(0,R.jsx)(`div`,{className:`runtime-subsection-group`,ref:V(`knowledge_dependencies`),children:(0,R.jsx)(Vq,{title:`知识库依赖`,items:Uq(Re,g),runtimeChannel:m.runtime_channel,installKind:`knowledge`,provider:m.knowledge_embedding_provider||`local_huggingface`,onStatusChange:ta})}),Pe?(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title`,children:`安装输出`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:Pe})]}):null,(g?.chromadbError||g?.sentenceTransformersError||g?.modelscopeError)&&(0,R.jsxs)(`div`,{className:`runtime-log-block`,children:[(0,R.jsxs)(`div`,{className:`settings-inline-alert warning runtime-inline-alert`,children:[(0,R.jsx)(`strong`,{children:`依赖损坏,需要重新安装`}),(0,R.jsx)(`span`,{children:`部分依赖包已安装但无法正常导入,请点击上方“重新安装知识库依赖”自动修复。`})]}),(0,R.jsx)(`span`,{className:`runtime-block-title runtime-block-title-warning`,children:`包导入错误`}),(0,R.jsxs)(`div`,{className:`runtime-error-stack`,children:[g.chromadbError&&(0,R.jsxs)(`div`,{className:`runtime-error-item`,children:[(0,R.jsx)(`span`,{className:`runtime-error-label`,children:`chromadb`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea`,rows:4,readOnly:!0,value:g.chromadbError})]}),g.sentenceTransformersError&&(0,R.jsxs)(`div`,{className:`runtime-error-item`,children:[(0,R.jsx)(`span`,{className:`runtime-error-label`,children:`sentence-transformers`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea`,rows:4,readOnly:!0,value:g.sentenceTransformersError})]}),g.modelscopeError&&(0,R.jsxs)(`div`,{className:`runtime-error-item`,children:[(0,R.jsx)(`span`,{className:`runtime-error-label`,children:`modelscope`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea`,rows:4,readOnly:!0,value:g.modelscopeError})]})]})]}),g?.knowledgeDependenciesError&&!g?.chromadbError&&!g?.sentenceTransformersError&&!g?.modelscopeError&&(0,R.jsxs)(`div`,{className:`runtime-log-block is-error`,children:[(0,R.jsx)(`span`,{className:`runtime-block-title runtime-block-title-danger`,children:`知识库依赖错误`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer runtime-error-textarea is-error`,rows:6,readOnly:!0,value:g.knowledgeDependenciesError})]})]})]}),g?.runtimeError?(0,R.jsx)(`div`,{className:`settings-form-group`,children:(0,R.jsxs)(`div`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`运行环境错误详情`}),(0,R.jsx)(`textarea`,{className:`textarea-field log-viewer`,rows:8,readOnly:!0,value:g.runtimeError})]})}):null]}),Pt===`logs`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`日志与控制`}),(0,R.jsx)(`p`,{children:`查看服务日志、管理后端进程、配置桌面行为与监听参数。`})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`服务状态`}),(0,R.jsxs)(`div`,{className:`control-status-row`,ref:V(`service_logs`),children:[(0,R.jsx)(`span`,{className:`helper-chip ${wr?`status-success`:Sr?`status-running`:`status-failed`}`,children:wr?`服务在线`:Sr?`启动中...`:`服务离线`}),(0,R.jsx)(`span`,{className:`helper-chip ${Sr?Cr?`status-success`:`status-running`:`status-pending`}`,children:Sr?Cr?`内置后端运行中`:`内置后端启动中`:`内置后端未运行`}),t.backend?.pid?(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`PID `,t.backend.pid]}):null]}),(0,R.jsxs)(`div`,{className:`cuda-insight-grid`,children:[(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`服务名`}),(0,R.jsx)(`span`,{className:`setting-value`,children:e.systemInfo?.application?.name||`-`})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`版本`}),(0,R.jsx)(`span`,{className:`setting-value`,children:e.systemInfo?.application?.version||`-`})]}),(0,R.jsxs)(`div`,{className:`setting-row`,children:[(0,R.jsx)(`span`,{className:`setting-label`,children:`日志文件`}),(0,R.jsx)(`span`,{className:`setting-value`,style:{fontSize:`0.82rem`,wordBreak:`break-all`,overflowWrap:`anywhere`},children:Tr})]})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`服务管理`}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`监听地址`}),(0,R.jsx)(`input`,{className:`settings-input-field`,ref:V(`host`),value:m.host,onChange:e=>B({...m,host:e.target.value})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`服务绑定的 IP 地址,默认 127.0.0.1。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`监听端口`}),(0,R.jsx)(`input`,{className:`settings-input-field`,ref:V(`port`),type:`number`,value:m.port,onChange:e=>B({...m,port:parseInt(e.target.value)||3838})}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`服务端口号,默认 3838。只有端口冲突或外部接入时再调整。`})]})]}),(0,R.jsxs)(`div`,{className:`desktop-actions`,children:[(0,R.jsx)(`button`,{className:Sr?`secondary-button danger-button`:`primary-button`,type:`button`,onClick:async()=>{Sr?(await window.desktop?.backend.stop(),pt(`内置后端已停止`)):(await window.desktop?.backend.start(),pt(`已请求启动内置后端`)),i(),await mr()},children:Sr?`停止内置后端`:`启动内置后端`}),Sr&&(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:async()=>{pt(`正在重启内置后端...`),await window.desktop?.backend.stop(),await new Promise(e=>setTimeout(e,1500)),await window.desktop?.backend.start(),pt(`内置后端已重启`),i(),await mr()},children:`重启后端`}),(0,R.jsx)(`button`,{className:`secondary-button danger-button`,type:`button`,disabled:!wr,onClick:async()=>{await L.shutdownService(),pt(`已向服务发送关闭请求`),i(),await mr()},children:`强制关闭服务`})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`桌面偏好`}),(0,R.jsxs)(`div`,{className:`settings-form-group`,children:[(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`开机自启动`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`系统启动时自动运行 BiliSum。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:te,onChange:async e=>{let t=e.target.checked,n=await window.desktop?.app?.setAutoLaunch(t);typeof n==`boolean`&&(P(n),n!==t&&w(`开机自启动${t?`开启`:`关闭`}失败,请检查系统权限`))}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`开机静默启动`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`开机自启时隐藏窗口,仅显示托盘图标。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:F,disabled:!te,onChange:async e=>{let t=e.target.checked;ne(t),await window.desktop?.preferences?.setSilentStart(t)}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`崩溃自动重启`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`后端服务非预期退出时自动拉起。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:re,onChange:async e=>{let t=e.target.checked;ie(t),await window.desktop?.preferences?.setCrashAutoRestart(t)}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsx)(`div`,{className:`settings-input-group`,children:(0,R.jsxs)(`div`,{className:`settings-toggle-row`,children:[(0,R.jsxs)(`div`,{className:`settings-toggle-label`,children:[(0,R.jsx)(`span`,{className:`settings-toggle-title`,children:`开发者模式`}),(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`开启后显示后台日志和浏览器开发者工具,便于调试问题。`})]}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:ae,onChange:async e=>{let t=e.target.checked;oe(t),await window.desktop?.preferences?.setDeveloperMode(t)}}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`关闭窗口行为`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,style:{maxWidth:200},value:N,onChange:async e=>{let t=e.target.value;ee(t),await window.desktop?.preferences?.setCloseBehavior(t)},children:[(0,R.jsx)(`option`,{value:`tray`,children:`最小化到托盘`}),(0,R.jsx)(`option`,{value:`exit`,children:`直接退出应用`})]}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`点击窗口关闭按钮时的行为。`})]})]}),(0,R.jsxs)(`div`,{className:`settings-reset-row`,children:[(0,R.jsxs)(`div`,{className:`settings-reset-row-copy`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`首页引导`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`重新显示首次进入首页的功能指引。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>{window.localStorage.removeItem(`bilisum.homeTourSeen`),window.localStorage.removeItem(`bilisum.summaryPreferenceHintSeen`),w(`已清空首页引导记录。`)},children:`重新显示`})]}),(0,R.jsxs)(`div`,{className:`settings-reset-row`,children:[(0,R.jsxs)(`div`,{className:`settings-reset-row-copy`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`配置引导`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`重新打开首次配置引导助手。`})]}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>{p(),w(`已打开配置引导。`)},children:`打开配置引导`})]})]}),(0,R.jsxs)(`div`,{className:`settings-cuda-section`,children:[(0,R.jsx)(`h3`,{className:`settings-cuda-title`,children:`日志`}),(0,R.jsx)(`div`,{className:`settings-input-group`,style:{marginBottom:12},children:(0,R.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:12,flexWrap:`wrap`},children:[(0,R.jsx)(`div`,{style:{display:`flex`,gap:6},children:[`all`,`ERROR`,`WARNING`,`INFO`].map(e=>(0,R.jsx)(`button`,{type:`button`,className:`filter-pill${le===e?` active`:``}`,onClick:()=>ue(e),children:e===`all`?`全部`:e},e))}),(0,R.jsx)(`div`,{style:{flex:1}}),(0,R.jsxs)(`div`,{className:`settings-toggle-row`,style:{gap:8},children:[(0,R.jsx)(`span`,{className:`settings-toggle-caption`,children:`自动刷新`}),(0,R.jsxs)(`label`,{className:`toggle-switch`,children:[(0,R.jsx)(`input`,{type:`checkbox`,checked:se,onChange:e=>ce(e.target.checked)}),(0,R.jsx)(`span`,{className:`toggle-slider`})]})]})]})}),(0,R.jsx)(`textarea`,{ref:de,className:`textarea-field log-viewer`,rows:22,readOnly:!0,value:hr||`暂无日志`}),(0,R.jsxs)(`div`,{className:`desktop-actions`,style:{marginTop:12},children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:()=>void mr(),children:`刷新日志`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:async()=>{await window.desktop?.shell.openPath(Tr)},children:`打开日志文件`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:async()=>{let e=await window.desktop?.logs?.exportLog?.();e&&pt(`日志已导出到 ${e}`)},children:`导出日志`}),(0,R.jsx)(`button`,{className:`secondary-button danger-button`,type:`button`,onClick:async()=>{await window.desktop?.logs?.clearLog?.(),await mr(),pt(`日志已清空`)},children:`清空日志`})]})]})]}),Pt===`updates`&&(0,R.jsxs)(`section`,{className:`settings-category-section`,children:[(0,R.jsxs)(`header`,{className:`settings-category-header`,children:[(0,R.jsx)(`h2`,{children:`桌面应用更新`}),(0,R.jsx)(`p`,{children:c?`检查新版本并管理安装。`:`查看最新版本信息与更新日志。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-module`,ref:V(`app_updates`),children:[(0,R.jsxs)(`div`,{className:`settings-update-overview`,children:[(0,R.jsxs)(`div`,{className:`settings-update-copy`,children:[(0,R.jsx)(`span`,{className:`settings-story-kicker`,children:`Update`}),(0,R.jsx)(`h3`,{children:c?`手动检查桌面端更新`:`手动检查最新版本`}),(0,R.jsx)(`p`,{children:ci})]}),(0,R.jsxs)(`div`,{className:`settings-update-badges`,children:[(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`当前版本 v`,ri]}),(0,R.jsxs)(`span`,{className:`helper-chip status-${si}`,children:[`状态:`,oi]}),o.version?(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`最新版本 v`,o.version]}):null,o.releaseDate?(0,R.jsxs)(`span`,{className:`helper-chip`,children:[`发布时间 `,sr(o.releaseDate)]}):null]})]}),(0,R.jsxs)(`div`,{className:`settings-update-grid`,children:[(0,R.jsxs)(`div`,{className:`settings-update-panel`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`当前安装版本`}),(0,R.jsxs)(`strong`,{children:[`v`,ri]}),(0,R.jsx)(`p`,{children:c?`检查、下载和安装更新。`:`当前环境仅支持检查最新版本。`})]}),(0,R.jsxs)(`div`,{className:`settings-update-panel ${o.status===`available`||o.status===`downloaded`?`is-highlight`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-update-label`,children:`检查结果`}),(0,R.jsx)(`strong`,{children:ai?`当前环境不可更新`:o.status===`available`||o.status===`downloaded`?`发现 v${o.version||`-`}`:o.status===`not-available`?`已是最新版本`:o.status===`error`?`检查失败`:o.status===`checking`?`正在检查`:o.status===`downloading`?`下载中 ${Math.round(o.downloadProgress)}%`:o.status===`installing`?`正在安装`:`等待检查`}),(0,R.jsx)(`p`,{children:!c&&o.status===`available`?`已检测到 v${o.version||`-`},请使用桌面安装包完成更新。`:!c&&o.status===`not-available`?`当前环境可查看最新版本信息,但不支持自动下载或安装。`:o.status===`available`||o.status===`downloaded`?`当前 v${ri},最新 v${o.version||`-`}`:o.status===`error`?o.errorMessage||`更新检查失败,请重试。`:ci})]})]}),(0,R.jsxs)(`div`,{className:`settings-update-actions`,children:[(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:!s||li,onClick:async()=>{try{if(!s)return;if(c&&o.status===`available`){await u();return}if(c&&o.status===`downloaded`){await d();return}await l()}catch{}},children:s?c?o.status===`checking`?`检查中...`:o.status===`downloading`?`下载中... ${Math.round(o.downloadProgress)}%`:o.status===`installing`?`安装中...`:o.status===`available`?`下载并重启安装`:o.status===`downloaded`?`立即重启安装`:o.status===`error`?`重试检查`:`检查更新`:o.status===`checking`?`检查中...`:`检查更新`:`当前环境无法检查更新`}),(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,disabled:!s,onClick:f,children:`查看更新详情`})]}),o.status===`available`||o.status===`downloaded`?(0,R.jsxs)(`div`,{className:`settings-update-next-step`,children:[(0,R.jsx)(`strong`,{children:`下一步`}),(0,R.jsx)(`span`,{children:c?o.status===`available`?`已检测到新版本,继续后会下载更新并自动重启安装。`:`更新已下载完成,可以立即重启应用完成安装。`:`当前环境仅支持查看最新版本信息,请前往桌面安装包完成更新。`})]}):null]})]}),(0,R.jsx)(`button`,{className:`settings-collapse-all-fab`,type:`button`,"aria-label":`回到顶部`,onClick:e=>{e.preventDefault(),fr()},title:`回到顶部`,children:(0,R.jsxs)(`svg`,{width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,R.jsx)(`polyline`,{points:`18 15 12 9 6 15`}),(0,R.jsx)(`line`,{x1:`12`,y1:`9`,x2:`12`,y2:`21`}),(0,R.jsx)(`line`,{x1:`6`,y1:`3`,x2:`18`,y2:`3`})]})})]})}),Ht?(0,R.jsx)(`div`,{className:`update-dialog-overlay`,role:`presentation`,onClick:ua,children:(0,R.jsxs)(`section`,{className:`update-dialog generation-model-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`generation-model-dialog-title`,onClick:e=>e.stopPropagation(),children:[(0,R.jsxs)(`header`,{className:`update-dialog-header`,children:[(0,R.jsxs)(`div`,{children:[(0,R.jsx)(`span`,{className:`settings-model-kicker`,children:`模型接入`}),(0,R.jsx)(`h2`,{id:`generation-model-dialog-title`,children:Ht===`main`?`主摘要模型`:`视觉理解模型`})]}),(0,R.jsx)(`button`,{className:`close-button`,type:`button`,"aria-label":`关闭模型配置`,onClick:ua,children:`×`})]}),(0,R.jsx)(`div`,{className:`update-dialog-body generation-model-dialog-body`,children:Ht===`main`?(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`LLM 提供商`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.llm_provider,onChange:e=>B({...m,llm_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI Compatible`}),(0,R.jsx)(`option`,{value:`openai`,children:`OpenAI`}),(0,R.jsx)(`option`,{value:`anthropic`,children:`Anthropic`}),(0,R.jsx)(`option`,{value:`custom`,children:`自建端点`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`llm_base_url`?`is-highlighted`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.llm_base_url,onChange:e=>B({...m,llm_base_url:e.target.value}),placeholder:`https://api.openai.com/v1`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`主摘要 LLM API 的基础 URL 地址。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`llm_api_key`?`is-highlighted`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.llm_api_key,onFocus:rJ,onChange:e=>B({...m,llm_api_key:e.target.value}),placeholder:`sk-...`}),(0,R.jsx)(`span`,{className:`settings-input-caption`,children:`已保存的密钥会用 ****** 显示,直接输入新值即可替换。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group settings-focus-target ${Rt===`llm_model`?`is-highlighted`:``}`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.llm_model,onChange:e=>B({...m,llm_model:e.target.value}),placeholder:`gpt-4o-mini / claude-3-haiku`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-alert ${Vr?`success`:`warning`}`,children:[(0,R.jsx)(`strong`,{children:Vr?`主摘要模型配置完整`:`主摘要模型仍需补全`}),(0,R.jsx)(`span`,{children:Vr?`可以保存后用于摘要、导图和默认视觉模型。`:`启用 LLM 摘要时,需要 Base URL、API Key 与模型名称都有效。`})]})]}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsxs)(`div`,{className:`settings-inline-alert info`,children:[(0,R.jsx)(`strong`,{children:`默认跟随主 LLM`}),(0,R.jsx)(`span`,{children:`视觉字段留空时,会复用主摘要模型的 Base URL、API Key 和模型名称;只有需要单独 VLM 时再填写。`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉模型提供商`}),(0,R.jsxs)(`select`,{className:`settings-select-field`,value:m.visual_vlm_provider||`openai-compatible`,onChange:e=>B({...m,visual_vlm_provider:e.target.value}),children:[(0,R.jsx)(`option`,{value:`openai-compatible`,children:`OpenAI Compatible`}),(0,R.jsx)(`option`,{value:`openai`,children:`OpenAI`}),(0,R.jsx)(`option`,{value:`anthropic`,children:`Anthropic`}),(0,R.jsx)(`option`,{value:`custom`,children:`自建端点`})]})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉 API Base URL`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.visual_evidence_base_url,onChange:e=>B({...m,visual_evidence_base_url:e.target.value}),placeholder:`留空则跟随主 LLM Base URL`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉模型名称`}),(0,R.jsx)(`input`,{className:`settings-input-field`,value:m.visual_evidence_model,onChange:e=>B({...m,visual_evidence_model:e.target.value}),placeholder:`留空则跟随主 LLM 模型`})]}),(0,R.jsxs)(`label`,{className:`settings-input-group`,children:[(0,R.jsx)(`span`,{className:`settings-input-label`,children:`视觉 API Key`}),(0,R.jsx)(`input`,{className:`settings-input-field`,type:`password`,value:m.visual_evidence_api_key,onFocus:rJ,onChange:e=>B({...m,visual_evidence_api_key:e.target.value}),placeholder:`留空则跟随主 LLM API Key`})]}),(0,R.jsxs)(`div`,{className:`settings-inline-alert ${Hr?`success`:`warning`}`,children:[(0,R.jsx)(`strong`,{children:Hr?`视觉模型配置完整`:`视觉模型会等待有效模型配置`}),(0,R.jsx)(`span`,{children:Hr?`当前有效配置可用于理解型图文笔记。`:`请补全独立视觉配置,或确保主摘要模型已完整配置。`})]})]})}),(0,R.jsxs)(`footer`,{className:`update-dialog-footer`,children:[(0,R.jsx)(`button`,{className:`secondary-button`,type:`button`,onClick:ua,children:`关闭`}),(0,R.jsx)(`button`,{className:`primary-button`,type:`button`,disabled:St,onClick:()=>void(Ht===`main`?sa():la()),children:St?`测试中...`:Ht===`main`?`测试主模型`:`测试视觉模型`})]})]})}):null,Bt?(0,R.jsx)(`div`,{className:`update-dialog-overlay`,role:`presentation`,onClick:()=>Vt(!1),children:(0,R.jsxs)(`section`,{className:`update-dialog knowledge-prompt-guide-dialog`,role:`dialog`,"aria-modal":`true`,"aria-labelledby":`knowledge-prompt-guide-title`,onClick:e=>e.stopPropagation(),children:[(0,R.jsxs)(`header`,{className:`update-dialog-header`,children:[(0,R.jsx)(`h2`,{id:`knowledge-prompt-guide-title`,children:`知识笔记提示词教程`}),(0,R.jsx)(`button`,{className:`close-button`,type:`button`,"aria-label":`关闭教程`,onClick:()=>Vt(!1),children:`×`})]}),(0,R.jsxs)(`div`,{className:`update-dialog-body knowledge-prompt-guide-body`,children:[(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`两个输入框分别控制什么`}),(0,R.jsx)(`p`,{children:`System Prompt 负责定义角色、底线和总体风格,例如"严谨的中文知识编辑""不得编造""只输出 JSON"。 User Template 负责规定笔记结构、可用素材和输出格式,是调整笔记样式的主要位置。`})]}),(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`可用变量`}),(0,R.jsxs)(`div`,{className:`knowledge-prompt-guide-grid`,children:[(0,R.jsx)(`span`,{children:`{title}`}),(0,R.jsx)(`p`,{children:`视频标题,适合用于生成笔记标题或判断主题。`}),(0,R.jsx)(`span`,{children:`{summary_json}`}),(0,R.jsx)(`p`,{children:`前一步结构化摘要,包含要点、章节、结论等信息。可以保留,也可以在模板里弱化它的权重。`}),(0,R.jsx)(`span`,{children:`{transcript_excerpt}`}),(0,R.jsx)(`p`,{children:`转写节选,适合补充细节和原文语境。`}),(0,R.jsx)(`span`,{children:`{segments_excerpt}`}),(0,R.jsx)(`p`,{children:`带时间或分段的信息,适合让笔记按章节展开。`})]})]}),(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`默认笔记格式`}),(0,R.jsx)(`p`,{children:`默认模板倾向生成一篇长阅读型 Markdown 笔记,通常包含:`}),(0,R.jsxs)(`ul`,{children:[(0,R.jsx)(`li`,{children:`核心结论:先给出视频最重要的观点。`}),(0,R.jsx)(`li`,{children:`关键概念:整理定义、条件、术语和背景。`}),(0,R.jsx)(`li`,{children:`章节展开:按内容推进顺序补全上下文。`}),(0,R.jsx)(`li`,{children:`易错点或限制:保留限制、争议、例外和注意事项。`})]})]}),(0,R.jsxs)(`section`,{className:`knowledge-prompt-guide-section`,children:[(0,R.jsx)(`h3`,{children:`怎么修改笔记样式`}),(0,R.jsx)(`p`,{children:`想改格式时,优先改 User Template 里的"写作要求"或"目标结构"。例如:`}),(0,R.jsx)(`pre`,{children:`请把 knowledgeNoteMarkdown 写成以下结构:
343
343
  # {title}
344
344
 
345
345
  ## 一句话总结
@@ -28,7 +28,7 @@
28
28
  :root[data-theme="light"] { --bg-base: #fafbfc; --bg-card: #ffffff; }
29
29
  html, body { margin: 0; height: 100%; overflow: hidden; background: var(--bg-base); }
30
30
  </style>
31
- <script type="module" crossorigin src="/static/assets/index-opES5zaV.js"></script>
31
+ <script type="module" crossorigin src="/static/assets/index-CrLCp2fw.js"></script>
32
32
  <link rel="stylesheet" crossorigin href="/static/assets/index-KvLZ2oI3.css">
33
33
  </head>
34
34
  <body>
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "video-sum-core"
7
- version = "1.20.0"
7
+ version = "1.20.1-alpha.1"
8
8
  description = "Core domain logic for the local video summarizer."
9
9
  requires-python = ">=3.12"
10
10
  dependencies = [
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "video-sum-infra"
7
- version = "1.20.0"
7
+ version = "1.20.1-alpha.1"
8
8
  description = "Infrastructure layer for the local video summarizer."
9
9
  requires-python = ">=3.12"
10
10
  dependencies = [
@@ -441,6 +441,45 @@ def runtime_python_executable(runtime_channel: str) -> Path | None:
441
441
  return None
442
442
 
443
443
 
444
+ def runtime_python_stdlib_healthy(runtime_dir: Path) -> bool:
445
+ """Cheap health check for a managed runtime interpreter directory.
446
+
447
+ The portable-CPython layout keeps the stdlib C extensions (``_socket.pyd``
448
+ etc.) in the ``DLLs`` directory listed by ``python312._pth``. A runtime
449
+ whose ``DLLs`` content went missing (interrupted refresh, partial copy)
450
+ still has ``python.exe`` and matching metadata, so the usual readiness
451
+ checks accept it — and then every subprocess dies with
452
+ ``ModuleNotFoundError: No module named '_socket'``.
453
+
454
+ Returns False only when the layout provably requires a ``DLLs`` directory
455
+ and the ``_socket`` extension is missing from it. Non-portable layouts
456
+ (plain venvs, dev-mode host interpreter) keep their extension modules
457
+ elsewhere and are always considered healthy here.
458
+
459
+ Takes the concrete runtime directory (not a channel name) so callers that
460
+ already resolved it — and tests that build fake runtime trees — get a
461
+ deterministic answer.
462
+ """
463
+ expects_dlls = False
464
+ pth_file = runtime_dir / "python312._pth"
465
+ if pth_file.exists():
466
+ try:
467
+ pth_lines = {
468
+ line.strip()
469
+ for line in pth_file.read_text(encoding="utf-8", errors="ignore").splitlines()
470
+ }
471
+ expects_dlls = "DLLs" in pth_lines
472
+ except OSError:
473
+ expects_dlls = False
474
+ if not expects_dlls:
475
+ return True
476
+
477
+ dlls_dir = runtime_dir / "DLLs"
478
+ if not dlls_dir.is_dir():
479
+ return False
480
+ return any(dlls_dir.glob("_socket*.pyd"))
481
+
482
+
444
483
  def ffmpeg_location() -> Path | None:
445
484
  """返回 ffmpeg 可执行文件的路径(不是目录)。"""
446
485
  ffmpeg_name = "ffmpeg.exe" if os.name == "nt" else "ffmpeg"
@@ -621,7 +660,10 @@ def bootstrap_managed_runtime(runtime_channel: str = "base") -> Path | None:
621
660
 
622
661
  seed_metadata = bundled_runtime_seed_metadata()
623
662
  runtime_metadata = read_runtime_metadata(runtime_dir)
624
- runtime_ready = runtime_python_executable(runtime_channel) is not None
663
+ runtime_ready = (
664
+ runtime_python_executable(runtime_channel) is not None
665
+ and runtime_python_stdlib_healthy(runtime_dir)
666
+ )
625
667
  seed_version = str(seed_metadata.get("appVersion") or "")
626
668
  runtime_version = str(runtime_metadata.get("appVersion") or "")
627
669
  can_preserve_extensions = (