Para «Rellenar con IA» de Eliminar en Labstream OS: la página manda el trozo de la foto
alrededor de lo pintado, en 8 bits con el hueco en el alfa, y la app lo devuelve con el
hueco relleno por LaMa y lo demás byte a byte como estaba (src-tauri/src/ia/relleno.rs).
- Comando nuevo ia_rellenar (permitido solo para el origen de la app). ia_estado e
ia_preparar llevan { que: "relleno" }; sin él siguen hablando del sujeto, como la 1.22,
y el estado dice ahora de qué IA habla (así la página sabe que esta app rellena).
- LaMa (Apache-2.0) en la exportación ONNX de tamaño libre de g-ronimo, desde el servidor
de la app con la sesión de la pestaña y fijada por huella (≈210 MB). Se rellena al
tamaño del trozo en múltiplos de 32, con 1024 px de lado como mucho.
- En la CPU: las dos exportaciones de LaMa probadas fallan con DirectML en una RTX 5080
(su FFT, sea el operador DFT o productos de matrices: 80070057, también con las formas
fijadas y sin optimizar); en la CPU, ~3 s a 512 px y ~10 s a 1024, y no le quita
memoria a la tarjeta.
- Las piezas por IA: el motor (ONNX Runtime + DirectML) es de las dos; cada modelo se baja
cuando se usa la suya. Cada modelo abierto se suelta a los 2 min sin uso.
Pruebas nuevas: el tamaño al que se rellena y que fuera del hueco no cambia nada; y una de
punta a punta en este equipo (ignorada en CI).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 líneas
5.4 KiB
TOML
99 líneas
5.4 KiB
TOML
[package]
|
|
name = "labstream-desktop"
|
|
version = "1.23.0"
|
|
description = "Cliente de escritorio de Labstream OS"
|
|
authors = ["Labstream SAS"]
|
|
edition = "2021"
|
|
rust-version = "1.77.2"
|
|
|
|
[lib]
|
|
name = "labstream_desktop_lib"
|
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
|
|
[build-dependencies]
|
|
tauri-build = { version = "2", features = [] }
|
|
|
|
[dependencies]
|
|
# `unstable` habilita multiwebview: varios webviews (pestañas) dentro de UNA ventana.
|
|
# `devtools` deja el inspector disponible TAMBIÉN en release (por defecto solo va en debug:
|
|
# wry-0.55.1/src/lib.rs:834-837). Sin él, un fallo que solo aparece en la app instalada —como
|
|
# el de OnlyOffice en Windows— no se puede mirar por dentro y hay que deducirlo leyendo
|
|
# fuentes. Con él, clic derecho → Inspeccionar sobre el marco que falle y se acabó.
|
|
tauri = { version = "2", features = ["tray-icon", "unstable", "devtools"] }
|
|
tauri-plugin-opener = "2"
|
|
tauri-plugin-clipboard-manager = "2"
|
|
tauri-plugin-notification = "2"
|
|
tauri-plugin-autostart = "2"
|
|
tauri-plugin-updater = "2"
|
|
tauri-plugin-single-instance = "2"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
# ── Diálogo «Guardar como» de las descargas (on_download en create_tab, lib.rs) ──
|
|
# rfd DIRECTO y no tauri-plugin-dialog: el manejador de descargas de wry exige la respuesta en
|
|
# el mismo hilo y de forma síncrona (WebView2 DownloadStarting / WKDownload
|
|
# decideDestination, ambos en el hilo principal). El `blocking_save_file()` del plugin monta
|
|
# el diálogo ASÍNCRONO (rfd::AsyncFileDialog) y espera en un canal; en macOS ese diálogo se
|
|
# presenta como hoja (beginSheetModalForWindow) y necesita que el run loop principal siga
|
|
# girando… que es justo el hilo que está bloqueado esperando el canal → cuelgue. El
|
|
# `rfd::FileDialog` síncrono corre un bucle modal anidado en el propio hilo
|
|
# (IFileDialog::Show / NSSavePanel.runModal), que es lo que hace falta aquí.
|
|
# Mismas features que usa el plugin oficial (common-controls-v6 = estilo moderno en Windows).
|
|
rfd = { version = "0.17", default-features = false, features = ["common-controls-v6"] }
|
|
# Para decodificar el último segmento de la URL cuando no hay nombre sugerido (macOS).
|
|
percent-encoding = "2"
|
|
# ── Rastreador de trabajo efectivo (src/tracker.rs) ──
|
|
# active-win-pos-rs: la ventana al frente (app + título) en Win/Mac.
|
|
# device_query: ¿hubo entrada? (huella de mouse/teclas presionadas; NUNCA qué se tecleó).
|
|
# ureq: subir los lotes a /api/tracker (bloqueante, corre en su propio hilo).
|
|
# gethostname: el nombre del equipo, que bautiza al device en el servidor.
|
|
active-win-pos-rs = "0.11"
|
|
ureq = { version = "2", features = ["json"] }
|
|
gethostname = "0.5"
|
|
# ── La IA del equipo (src/ia, 1.22) ──
|
|
# sha2: la huella de lo que se baja (modelo y motor); zip: sacar las DLL del paquete del motor.
|
|
sha2 = "0.10"
|
|
zip = { version = "4", default-features = false, features = ["deflate"] }
|
|
|
|
# device_query solo en Windows/Linux: la huella de entrada (posición del mouse + cuántas teclas
|
|
# hay presionadas). En macOS NO se usa —leer el teclado global dispara el permiso de
|
|
# Accesibilidad y el diálogo «… quiere controlar este ordenador»— y se sustituye por
|
|
# CGEventSourceSecondsSinceLastEventType (idle_seconds_macos en tracker.rs), que no pide permiso.
|
|
[target.'cfg(not(target_os = "macos"))'.dependencies]
|
|
device_query = "4"
|
|
|
|
# ── Excepción del video (Windows) ──
|
|
# Para saber si «hay un video reproduciéndose» sin espiar el navegador: se mira el MEDIDOR de
|
|
# la salida de audio por defecto (WASAPI, IAudioMeterInformation). Si al frente hay un navegador
|
|
# y está saliendo sonido, es un video sonando → cuenta como navegador, no como inactividad.
|
|
# Solo Windows: en macOS no hay API pública sencilla de nivel de audio por app (el equipo de
|
|
# edición es Windows). El `windows` crate ya está en la caché por Tauri.
|
|
[target.'cfg(windows)'.dependencies]
|
|
# IA del equipo (1.22, src/ia/motor.rs): ONNX Runtime con DirectML sobre la tarjeta. `load-dynamic`:
|
|
# nada se enlaza al compilar; la DLL (la de DirectML 1.24, de NuGet) se baja la primera vez y se
|
|
# carga desde la carpeta de la IA. `api-24`: la versión de la API que trae esa DLL.
|
|
ort = { version = "=2.0.0-rc.14", default-features = false, features = ["std", "load-dynamic", "directml", "api-24"] }
|
|
# Pestañas en reposo (1.19): ICoreWebView2_3::TrySuspend. Es la misma versión que ya trae Tauri.
|
|
webview2-com = "0.38"
|
|
windows = { version = "0.61", features = [
|
|
"Win32_Foundation",
|
|
"Win32_System_Com",
|
|
# IMMDevice::Activate exige AMBAS (su firma lleva un PROPVARIANT): sin ellas el método
|
|
# queda cfg'd out y «no existe». Verificado con cargo check --target windows-msvc.
|
|
"Win32_System_Com_StructuredStorage",
|
|
"Win32_System_Variant",
|
|
"Win32_Media_Audio",
|
|
"Win32_Media_Audio_Endpoints",
|
|
# Salud (1.20): medir el árbol de procesos (exe + WebView2) y el reinicio automático de Windows.
|
|
"Win32_System_Diagnostics_ToolHelp",
|
|
"Win32_System_ProcessStatus",
|
|
"Win32_System_Threading",
|
|
"Win32_System_Recovery",
|
|
# Memoria (1.20): ¿cuánto lleva el equipo sin tocar? (para reciclar el proceso gráfico sin que se note)
|
|
"Win32_UI_Input_KeyboardAndMouse",
|
|
"Win32_System_SystemInformation",
|
|
# IA del equipo (1.22): ¿hay tarjeta NVIDIA? (los adaptadores de DXGI)
|
|
"Win32_Graphics_Dxgi",
|
|
# y cargar DirectML.dll por su ruta antes que ONNX Runtime (src/ia/motor.rs)
|
|
"Win32_System_LibraryLoader",
|
|
] }
|