Files
Dione/Dione/ViewModels/SettingsViewModel.cs
T
Alby96 a768fb8e04 Creazione progetto SynthData Pro: struttura WPF completa
Aggiunti tutti i file sorgente per la nuova applicazione desktop WPF "SynthData Pro" (namespace Dione) per la generazione dati tramite LLM locale/remoto.
Inclusi:
- Progetto .csproj, configurazione .NET 4.8.1, risorse e file di soluzione.
- UI moderna con Material Design, sidebar, title bar custom, e navigazione tra Dashboard, Generazione Live, Impostazioni e Telemetria.
- Modelli dati (AppSettings, DataProject, SchemaColumn, TelemetryLog) e layer dati SQLite con migrazione automatica.
- ViewModel principali per dashboard KPI/grafici, generazione streaming, impostazioni, telemetria.
- Tutte le View XAML e relativi code-behind.
- Localizzazione italiana e attenzione all'usabilità.
- Pronto per estensioni future (Data Designer, moduli placeholder).
2026-04-21 23:19:50 +02:00

303 lines
16 KiB
C#

using System;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Dione.Data;
using Dione.Models;
using Microsoft.Win32;
namespace Dione.ViewModels
{
public class SettingsViewModel : ObservableObject
{
// ── API ──────────────────────────────────────────────────────────────────
private string _selectedEndpointPreset = "Custom";
public string SelectedEndpointPreset
{
get => _selectedEndpointPreset;
set { if (SetProperty(ref _selectedEndpointPreset, value) && value != "Custom") ApplyPreset(value); }
}
public string[] EndpointPresets { get; } = { "Custom", "OpenAI", "Anthropic", "Google AI", "Azure OpenAI", "LM Studio (Local)", "Ollama (Local)" };
private string _apiEndpoint = "http://127.0.0.1:1234/v1/chat/completions";
public string ApiEndpoint { get => _apiEndpoint; set => SetProperty(ref _apiEndpoint, value); }
private string _modelName = "";
public string ModelName { get => _modelName; set => SetProperty(ref _modelName, value); }
private string _apiKey = "";
public string ApiKey { get => _apiKey; set => SetProperty(ref _apiKey, value); }
private double _temperature = 0.7;
public double Temperature { get => _temperature; set => SetProperty(ref _temperature, value); }
private int _maxTokens = 2048;
public int MaxTokens { get => _maxTokens; set => SetProperty(ref _maxTokens, value); }
// ── Prompt ───────────────────────────────────────────────────────────────
private string _systemPrompt = "";
public string SystemPrompt { get => _systemPrompt; set => SetProperty(ref _systemPrompt, value); }
private string _userPrompt = "";
public string UserPrompt { get => _userPrompt; set => SetProperty(ref _userPrompt, value); }
// ── Output ───────────────────────────────────────────────────────────────
private string _outputDirectory = "";
public string OutputDirectory { get => _outputDirectory; set => SetProperty(ref _outputDirectory, value); }
private string _outputFilePrefix = "batch";
public string OutputFilePrefix { get => _outputFilePrefix; set => SetProperty(ref _outputFilePrefix, value); }
private int _maxFileSizeMb = 250;
public int MaxFileSizeMb { get => _maxFileSizeMb; set => SetProperty(ref _maxFileSizeMb, value); }
// ── Timeout ──────────────────────────────────────────────────────────────
private int _apiTimeoutSeconds = 120;
public int ApiTimeoutSeconds { get => _apiTimeoutSeconds; set => SetProperty(ref _apiTimeoutSeconds, value); }
private double _timeoutPerTokenRatio = 0.5;
public double TimeoutPerTokenRatio { get => _timeoutPerTokenRatio; set => SetProperty(ref _timeoutPerTokenRatio, value); }
// ── Verifica qualita ─────────────────────────────────────────────────────
private bool _enableQualityVerification = false;
public bool EnableQualityVerification { get => _enableQualityVerification; set => SetProperty(ref _enableQualityVerification, value); }
private bool _useSameModelForVerification = true;
public bool UseSameModelForVerification { get => _useSameModelForVerification; set => SetProperty(ref _useSameModelForVerification, value); }
private string _verificationApiEndpoint = "";
public string VerificationApiEndpoint { get => _verificationApiEndpoint; set => SetProperty(ref _verificationApiEndpoint, value); }
private string _verificationModelName = "";
public string VerificationModelName { get => _verificationModelName; set => SetProperty(ref _verificationModelName, value); }
private string _verificationApiKey = "";
public string VerificationApiKey { get => _verificationApiKey; set => SetProperty(ref _verificationApiKey, value); }
private double _revenuePerHighQualityRecord = 0.005;
public double RevenuePerHighQualityRecord { get => _revenuePerHighQualityRecord; set => SetProperty(ref _revenuePerHighQualityRecord, value); }
// ── Costi ────────────────────────────────────────────────────────────────
private double _electricityCostPerKwh = 0.25;
public double ElectricityCostPerKwh { get => _electricityCostPerKwh; set => SetProperty(ref _electricityCostPerKwh, value); }
private double _systemPowerWatt = 350;
public double SystemPowerWatt { get => _systemPowerWatt; set => SetProperty(ref _systemPowerWatt, value); }
private string _apiCostType = "Free";
public string ApiCostType { get => _apiCostType; set => SetProperty(ref _apiCostType, value); }
public string[] ApiCostTypes { get; } = { "Free", "PerCall", "PerBlock" };
private double _apiCostPerCall = 0;
public double ApiCostPerCall { get => _apiCostPerCall; set => SetProperty(ref _apiCostPerCall, value); }
private double _apiCostPerBlock = 0;
public double ApiCostPerBlock { get => _apiCostPerBlock; set => SetProperty(ref _apiCostPerBlock, value); }
private int _apiBlockSize = 1000;
public int ApiBlockSize { get => _apiBlockSize; set => SetProperty(ref _apiBlockSize, value); }
// ── Status ───────────────────────────────────────────────────────────────
private string _statusMessage = "";
public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); }
// ── Commands ─────────────────────────────────────────────────────────────
public RelayCommand SaveCommand { get; }
public RelayCommand BrowseOutputDirectoryCommand { get; }
public RelayCommand ResetTelemetryCommand { get; }
public RelayCommand ResetDatabaseCommand { get; }
public RelayCommand InsertDefaultBettingPromptCommand { get; }
// ── Constructor ──────────────────────────────────────────────────────────
public SettingsViewModel()
{
SaveCommand = new RelayCommand(Save);
BrowseOutputDirectoryCommand = new RelayCommand(BrowseOutputDirectory);
ResetTelemetryCommand = new RelayCommand(ResetTelemetry);
ResetDatabaseCommand = new RelayCommand(ResetDatabase);
InsertDefaultBettingPromptCommand = new RelayCommand(InsertDefaultBettingPrompt);
Load();
}
// ── Private methods ──────────────────────────────────────────────────────
public void Load()
{
try
{
var s = SynthDataDbContext.LoadSettings();
ApiEndpoint = s.ApiEndpoint;
ModelName = s.ModelName;
ApiKey = s.ApiKey;
Temperature = s.Temperature;
MaxTokens = s.MaxTokens;
SystemPrompt = s.SystemPrompt;
UserPrompt = s.UserPrompt;
OutputDirectory = s.OutputDirectory;
OutputFilePrefix = s.OutputFilePrefix;
MaxFileSizeMb = s.MaxFileSizeMb;
ApiTimeoutSeconds = s.ApiTimeoutSeconds;
TimeoutPerTokenRatio = s.TimeoutPerTokenRatio;
EnableQualityVerification = s.EnableQualityVerification;
UseSameModelForVerification = s.UseSameModelForVerification;
VerificationApiEndpoint = s.VerificationApiEndpoint;
VerificationModelName = s.VerificationModelName;
VerificationApiKey = s.VerificationApiKey;
RevenuePerHighQualityRecord = s.RevenuePerHighQualityRecord;
ElectricityCostPerKwh = s.ElectricityCostPerKwh;
SystemPowerWatt = s.SystemPowerWatt;
ApiCostType = s.ApiCostType;
ApiCostPerCall = s.ApiCostPerCall;
ApiCostPerBlock = s.ApiCostPerBlock;
ApiBlockSize = s.ApiBlockSize;
StatusMessage = "Impostazioni caricate.";
}
catch (Exception ex)
{
StatusMessage = "Errore caricamento: " + ex.Message;
}
}
private void Save()
{
if (string.IsNullOrWhiteSpace(OutputDirectory))
{
StatusMessage = "Seleziona una cartella di output.";
return;
}
try
{
SynthDataDbContext.SaveSettings(new AppSettings
{
ApiEndpoint = ApiEndpoint,
ModelName = ModelName,
ApiKey = ApiKey,
Temperature = Temperature,
MaxTokens = MaxTokens,
SystemPrompt = SystemPrompt,
UserPrompt = UserPrompt,
OutputDirectory = OutputDirectory,
OutputFilePrefix = OutputFilePrefix,
MaxFileSizeMb = MaxFileSizeMb,
ApiTimeoutSeconds = ApiTimeoutSeconds,
TimeoutPerTokenRatio = TimeoutPerTokenRatio,
EnableQualityVerification = EnableQualityVerification,
UseSameModelForVerification = UseSameModelForVerification,
VerificationApiEndpoint = VerificationApiEndpoint,
VerificationModelName = VerificationModelName,
VerificationApiKey = VerificationApiKey,
RevenuePerHighQualityRecord = RevenuePerHighQualityRecord,
ElectricityCostPerKwh = ElectricityCostPerKwh,
SystemPowerWatt = SystemPowerWatt,
ApiCostType = ApiCostType,
ApiCostPerCall = ApiCostPerCall,
ApiCostPerBlock = ApiCostPerBlock,
ApiBlockSize = ApiBlockSize,
});
StatusMessage = "Impostazioni salvate.";
}
catch (Exception ex)
{
StatusMessage = "Errore salvataggio: " + ex.Message;
}
}
private void BrowseOutputDirectory()
{
var dlg = new System.Windows.Forms.FolderBrowserDialog
{
Description = "Seleziona la cartella di output",
SelectedPath = OutputDirectory
};
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
OutputDirectory = dlg.SelectedPath;
}
private void ResetTelemetry()
{
if (MessageBox.Show("Eliminare TUTTA la telemetria?", "Conferma", MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes)
return;
try { SynthDataDbContext.DeleteAllTelemetry(); StatusMessage = "Telemetria eliminata."; }
catch (Exception ex) { StatusMessage = "Errore: " + ex.Message; }
}
private void ResetDatabase()
{
if (MessageBox.Show("Resettare COMPLETAMENTE il database? Tutte le impostazioni e la telemetria verranno cancellate.",
"Conferma Reset", MessageBoxButton.YesNo, MessageBoxImage.Stop) != MessageBoxResult.Yes)
return;
try { SynthDataDbContext.ResetDatabase(); Load(); StatusMessage = "Database resettato."; }
catch (Exception ex) { StatusMessage = "Errore: " + ex.Message; }
}
private void InsertDefaultBettingPrompt()
{
SystemPrompt =
"Sei il nodo validatore di una blockchain per una piattaforma di scommesse decentralizzata. " +
"Il tuo compito e generare transazioni fittizie ma realistiche in formato JSON puro. " +
"Non includere testo introduttivo o conclusivo, restituisci solo un array di oggetti JSON.\n\n" +
"Regole per la generazione dei dati:\n" +
"- Ogni transazione deve avere un tx_hash esadecimale casuale di 64 caratteri e un timestamp ISO 8601.\n" +
"- bet_type puo essere solo 'singola' o 'multipla'.\n" +
"- Genera un bankroll_at_time casuale tra 100 e 5000.\n" +
"- Logica dello Stake: Se 'singola', stake_amount deve essere intero e multiplo di 5. " +
"Se 'multipla', genera confidence_level tra 0.0 e 1.0. Se confidenza tra 0.9 e 1.0, " +
"stake_amount fino al 10% del bankroll. Altrimenti sotto l'1%.\n" +
"- Includi smart_contract_log che spiega come lo smart contract ha processato i fondi.";
UserPrompt = "Genera un blocco di 5 nuove transazioni sequenziali rispettando rigorosamente le regole di business.";
StatusMessage = "Prompt blockchain betting inseriti. Ricorda di salvare.";
}
private void ApplyPreset(string preset)
{
switch (preset)
{
case "OpenAI":
ApiEndpoint = "https://api.openai.com/v1/chat/completions";
ModelName = "gpt-4o";
StatusMessage = "Preset OpenAI applicato. Inserisci la API Key.";
break;
case "Anthropic":
ApiEndpoint = "https://api.anthropic.com/v1/messages";
ModelName = "claude-3-5-sonnet-20241022";
StatusMessage = "Preset Anthropic applicato. Inserisci la API Key.";
break;
case "Google AI":
ApiEndpoint = "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions";
ModelName = "gemini-2.0-flash-exp";
StatusMessage = "Preset Google AI applicato. Inserisci la API Key.";
break;
case "Azure OpenAI":
ApiEndpoint = "https://<resource>.openai.azure.com/openai/deployments/<deployment>/chat/completions?api-version=2024-02-15-preview";
ModelName = "gpt-4";
StatusMessage = "Sostituisci <resource> e <deployment>.";
break;
case "LM Studio (Local)":
ApiEndpoint = "http://127.0.0.1:1234/v1/chat/completions";
ModelName = "";
ApiKey = "";
StatusMessage = "Preset LM Studio applicato.";
break;
case "Ollama (Local)":
ApiEndpoint = "http://127.0.0.1:11434/v1/chat/completions";
ModelName = "llama3.3";
ApiKey = "";
StatusMessage = "Preset Ollama applicato.";
break;
}
}
}
}