feat: enhance OllaHub with new features and UI improvements
- Introduced a comprehensive README.md detailing the application, its architecture, and key features. - Implemented a local-first architecture with deep research capabilities, including query decomposition and parallel web scraping. - Added a reactive UI built with React and Next.js, featuring Tailwind CSS for styling and Zustand for state management. - Integrated a task scheduler for recurring tasks and system monitoring for real-time resource management. - Enhanced settings page with debug mode options and improved hardware dashboard loading states. - Updated chat interface to include debug data visualization and improved user experience during message streaming. - Removed unused favicon and updated application icons for better branding. - Improved navigation handling with non-blocking transitions and state management for setup completion.
No files matched your search
|
After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 136 KiB |
@@ -6,7 +6,7 @@ use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tauri::{command, Window, Emitter, Manager, AppHandle, State};
|
||||
use tauri::{command, Window, Emitter, Manager, AppHandle, State, WebviewWindow};
|
||||
use sysinfo::System;
|
||||
use chrono::{DateTime, Utc};
|
||||
use zip::write::{FileOptions, ZipWriter};
|
||||
@@ -328,6 +328,23 @@ fn get_mcp_config_path(app_handle: &AppHandle) -> Result<PathBuf, String> {
|
||||
Ok(app_data_dir.join("mcp_config.json"))
|
||||
}
|
||||
|
||||
#[command]
|
||||
fn toggle_devtools(window: WebviewWindow) -> Result<(), String> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if window.is_devtools_open() {
|
||||
window.close_devtools();
|
||||
} else {
|
||||
window.open_devtools();
|
||||
}
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
// Em release, não fazer nada
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
fn save_chat_session(
|
||||
app_handle: AppHandle,
|
||||
@@ -3697,6 +3714,7 @@ pub fn run() {
|
||||
delete_model,
|
||||
save_chat_session,
|
||||
load_chat_sessions,
|
||||
toggle_devtools,
|
||||
search_chat_sessions,
|
||||
load_chat_history,
|
||||
load_chat_history_paginated,
|
||||
|
||||
@@ -210,6 +210,7 @@ pub fn detect_all_gpus() -> Vec<GpuInfo> {
|
||||
#[cfg(target_os = "windows")]
|
||||
fn detect_gpus_windows() -> Vec<GpuInfo> {
|
||||
use std::process::Command;
|
||||
use std::os::windows::process::CommandExt;
|
||||
let mut gpus = Vec::new();
|
||||
|
||||
log::info!("Tentando detectar GPUs via wmic...");
|
||||
@@ -217,6 +218,7 @@ fn detect_gpus_windows() -> Vec<GpuInfo> {
|
||||
// Tentar formato CSV primeiro (mais confiável)
|
||||
if let Ok(output) = Command::new("wmic")
|
||||
.args(&["path", "win32_VideoController", "get", "name,AdapterRAM,PNPDeviceID", "/format:csv"])
|
||||
.creation_flags(0x08000000) // CREATE_NO_WINDOW
|
||||
.output()
|
||||
{
|
||||
// wmic pode retornar UTF-16LE no Windows, precisamos converter
|
||||
@@ -282,6 +284,7 @@ fn detect_gpus_windows() -> Vec<GpuInfo> {
|
||||
// Fallback para formato list
|
||||
if let Ok(output) = Command::new("wmic")
|
||||
.args(&["path", "win32_VideoController", "get", "name,AdapterRAM,PNPDeviceID", "/format:list"])
|
||||
.creation_flags(0x08000000) // CREATE_NO_WINDOW
|
||||
.output()
|
||||
{
|
||||
if let Ok(stdout) = String::from_utf8(output.stdout) {
|
||||
@@ -337,11 +340,13 @@ fn detect_gpus_windows() -> Vec<GpuInfo> {
|
||||
#[cfg(target_os = "windows")]
|
||||
fn detect_gpus_nvidia_smi() -> Result<Vec<GpuInfo>, String> {
|
||||
use std::process::Command;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
log::info!("Executando nvidia-smi...");
|
||||
|
||||
let output = Command::new("nvidia-smi")
|
||||
.args(&["--query-gpu=name,memory.total", "--format=csv,noheader,nounits"])
|
||||
.creation_flags(0x08000000) // CREATE_NO_WINDOW
|
||||
.output()
|
||||
.map_err(|e| format!("nvidia-smi não encontrado: {}", e))?;
|
||||
|
||||
@@ -678,13 +683,19 @@ fn get_nvidia_gpu_stats(gpu: &GpuInfo) -> Option<GpuStats> {
|
||||
// Query nvidia-smi para obter todas as métricas
|
||||
let query = "name,memory.used,memory.total,utilization.gpu,utilization.memory,temperature.gpu,temperature.max,power.draw,power.limit,fan.speed,driver_version";
|
||||
|
||||
let output = Command::new("nvidia-smi")
|
||||
.args(&[
|
||||
"--query-gpu", query,
|
||||
"--format=csv,noheader,nounits"
|
||||
])
|
||||
.output()
|
||||
.ok()?;
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
let mut cmd = Command::new("nvidia-smi");
|
||||
cmd.args(&[
|
||||
"--query-gpu", query,
|
||||
"--format=csv,noheader,nounits"
|
||||
]);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
|
||||
|
||||
let output = cmd.output().ok()?;
|
||||
|
||||
if !output.status.success() {
|
||||
log::warn!("nvidia-smi falhou ao coletar stats");
|
||||
@@ -757,9 +768,16 @@ fn get_nvidia_gpu_stats(gpu: &GpuInfo) -> Option<GpuStats> {
|
||||
fn count_nvidia_gpu_processes() -> Result<usize, String> {
|
||||
use std::process::Command;
|
||||
|
||||
let output = Command::new("nvidia-smi")
|
||||
.args(&["--query-compute-apps=pid", "--format=csv,noheader"])
|
||||
.output()
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
let mut cmd = Command::new("nvidia-smi");
|
||||
cmd.args(&["--query-compute-apps=pid", "--format=csv,noheader"]);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
|
||||
|
||||
let output = cmd.output()
|
||||
.map_err(|e| format!("nvidia-smi não encontrado: {}", e))?;
|
||||
|
||||
if !output.status.success() {
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"resizable": true,
|
||||
"fullscreen": false,
|
||||
"decorations": false,
|
||||
"transparent": false
|
||||
"transparent": false,
|
||||
"devtools": false
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
@@ -29,11 +30,12 @@
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
"icons/icon.ico",
|
||||
"icons/32x32.ico",
|
||||
"icons/128x128.ico",
|
||||
"icons/256x256.ico",
|
||||
"icons/512x512.ico",
|
||||
"icons/icon.icns"
|
||||
]
|
||||
},
|
||||
"plugins": {
|
||||
|
||||