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 +1 -1
- package/runtime/VERSION +1 -1
- package/runtime/apps/service/pyproject.toml +1 -1
- package/runtime/apps/service/src/video_sum_service/routers/system.py +27 -8
- package/runtime/apps/service/src/video_sum_service/runtime_support.py +113 -8
- package/runtime/apps/service/src/video_sum_service/settings_manager.py +28 -13
- package/runtime/apps/web/static/assets/{index-opES5zaV.js → index-CrLCp2fw.js} +1 -1
- package/runtime/apps/web/static/index.html +1 -1
- package/runtime/packages/core/pyproject.toml +1 -1
- package/runtime/packages/infra/pyproject.toml +1 -1
- package/runtime/packages/infra/src/video_sum_infra/runtime.py +43 -1
package/package.json
CHANGED
package/runtime/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.20.
|
|
1
|
+
1.20.1-alpha.1
|
|
@@ -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
|
-
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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 =
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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=
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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-
|
|
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>
|
|
@@ -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 =
|
|
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 = (
|