CoolFace
Apppublic

localailb/assistant

sourceHugging Facemitupdated 1mo agoView on Hugging Face
0likes
app.py77 linesDownload Raw Back to root
1"""
2LocalAiLab Assistant โ€” by LocalAiLab
3smolagents + ChromaDB + Dynamic Hardware Support + Svelte Web UI
4=======================================================================
5Tabs:
6  ๐Ÿ’ฌ General Chat  โ€” direct LLM conversation, no retrieval
7  ๐Ÿ“š RAG Chat      โ€” retrieves from ChromaDB before answering
8  ๐Ÿ”ฌ Deep Research โ€” iterative multi-agent web research
9  ๐Ÿ–ผ๏ธ Vision Chat   โ€” image upload, answers from the image only (no KB)
10  ๐ŸŽ™๏ธ Speech to Text โ€” transcribe audio to text using Whisper
11  ๐Ÿ“Š Data Analysis โ€” AI agent explores CSV/Excel, builds charts + report
12  ๐Ÿ“‚ Knowledge Base โ€” index / manage documents
13  โš™๏ธ Settings      โ€” system & model configuration
14  โ„น๏ธ About         โ€” bilingual system info
15"""
16
17import os
18import socket
19import threading
20import warnings
21import webbrowser
22from pathlib import Path
23
24os.environ.setdefault("HF_HUB_DISABLE_TELEMETRY", "1")
25os.environ.setdefault("DO_NOT_TRACK", "1")
26# Force the non-GUI matplotlib backend app-wide (see run_webview.py โ€” the
27# tkinter splash must never collide with matplotlib's TkAgg auto-select in
28# the Data worker thread; `Tcl_AsyncDelete` would abort the process).
29os.environ.setdefault("MPLBACKEND", "Agg")
30
31try:
32    from dotenv import load_dotenv
33    from backend.paths import user_data_dir
34
35    user_env = str(user_data_dir() / ".env")
36    if os.path.exists(user_env):
37        load_dotenv(user_env)
38    else:
39        load_dotenv()
40except ImportError:
41    pass
42
43from backend import web_api
44
45APP_ICON = Path(__file__).parent / "ui" / "image" / "logo_round.png"
46
47
48def _find_free_port(start=7861):
49    for port in range(start, start + 20):
50        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
51            if s.connect_ex(("127.0.0.1", port)) != 0:
52                return port
53    return start
54
55
56warnings.filterwarnings("ignore", category=UserWarning, module="torch")
57
58if __name__ == "__main__":
59    import multiprocessing
60
61    multiprocessing.freeze_support()
62
63    # Shared Windows stdio hardening: replaces None OR broken-handle
64    # streams (a GUI-launched process can have a sys.stdout whose OS handle
65    # is invalid โ€” print() then raises OSError [WinError 6] and kills the
66    # run) and forces UTF-8 + errors=replace on the rest.
67    from backend.stdio_hardening import harden_stdio, harden_subprocesses
68    from backend.metadata_hardening import harden_metadata
69    harden_stdio()
70    harden_subprocesses()
71    harden_metadata()
72
73    port = _find_free_port()
74    # Open browser on startup
75    threading.Timer(0.8, lambda: webbrowser.open(f"http://127.0.0.1:{port}")).start()
76    web_api.run(host="127.0.0.1", port=port, log_level="info")
77