添加项目文件。

This commit is contained in:
yangwx
2025-03-12 20:02:52 +08:00
parent 4d34907fa7
commit 3ccd6d9a39
32 changed files with 1833 additions and 0 deletions

View File

@@ -0,0 +1,298 @@
using OllamaSharp;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows;
namespace YwxApp.AiChat.ViewModels
{
/// <summary>
/// 0、Current class:
/// </summary>
public class ShareOllamaObject
{
#region Field | Property | Collection | Command
#region Field
private bool _ollamaEnabled = false; //ollama connected state
private string _ollamaAppPath; //ollama app path.
private int recordIndex = 0; //current record index.
private string _currentPath; //current record;
private Chat chat; //build interactive chat model object.
private OllamaApiClient _ollama; //OllamaAPI object.
#endregion
#region Property
public string OllamaAppPath
{
get { return _ollamaAppPath; }
set { _ollamaAppPath = value; }
}
public bool OllamaEnabled
{
get { return _ollamaEnabled; }
set { _ollamaEnabled = value; }
}
public OllamaApiClient Ollama
{
get { return _ollama; }
set { _ollama = value; }
}
public Chat Chat
{
get { return chat; }
set { chat = value; }
}
public string CurrentPath
{
get => _currentPath;
}
public int RecordIndex
{
get => recordIndex;
set
{
recordIndex = value;
_currentPath = $"{Environment.CurrentDirectory}//Data//{DateTime.Today.ToString("yyyyMMdd")}" +
$"//{DateTime.Today.ToString("yyyyMMdd")}_{recordIndex}.txt";
}
}
#endregion
#region Collection
public ObservableCollection<string> ModelList { get; set; }
#endregion
#endregion
#region Constructor
public ShareOllamaObject()
{
RecordIndex = 0;
WriteDataToFileAsync("");
Init(OllamaAppPath, "llama3.2:9b");
}
#endregion
#region other method
/// <summary>
/// initialite method
/// </summary>
private void Init(string appPath, string modelName)
{
OllamaAppPath = appPath;
try
{
// 设置默认设备为GPU
Environment.SetEnvironmentVariable("OLLAMA_DEFAULT_DEVICE", "gpu");
//判断路径是否存在
if (OllamaAppPath == string.Empty || OllamaAppPath == null) OllamaAppPath = @"ollama app.exe";
//路径存在获取应用名
if (File.Exists(OllamaAppPath)) OllamaAppPath = Path.GetFileName(OllamaAppPath);
//获取环境Ollama环境变量用于找到 ollama app.exe
var filePath = FindExeInPath(OllamaAppPath);
//如果路径存在启动Ollama
if (File.Exists(filePath)) CheckStartProcess(OllamaAppPath);
//连接Ollama并设置初始模型
_ollama = new OllamaApiClient(new Uri("http://localhost:11434"));
//获取本地可用的模型列表
ModelList = (ObservableCollection<string>)GetModelList();
var tmepModelName = ModelList.FirstOrDefault(name => name.ToLower().Contains("llama3.2"));
if (tmepModelName != null) _ollama.SelectedModel = tmepModelName;
else if (ModelList.Count > 0) _ollama.SelectedModel = ModelList[ModelList.Count - 1];
if (ModelList.FirstOrDefault(name => name.Equals(modelName)) != null) _ollama.SelectedModel = modelName;
//Ollama服务启用成功
OllamaEnabled = true;
}
catch (Exception)
{
OllamaEnabled = false;
}
}
/// <summary>
/// update the model selected by Ollama
/// </summary>
public void UpdataSelectedModel(string model)
{
Ollama.SelectedModel = model;
OllamaEnabled = true;
}
/// <summary>
/// Start Ollama app and relevant server.
/// </summary>
public async void StartOllama(string appPath, string modelName)
{
Init(appPath, modelName); await Task.Delay(1);
}
/// <summary>
/// get model list
/// </summary>
public Collection<string> GetModelList()
{
var models = _ollama.ListLocalModelsAsync();
var modelList = new ObservableCollection<string>();
foreach (var model in models.Result)
{
modelList.Add(model.Name);
}
return modelList;
}
#endregion
#region starting or closeing method of Ollama(server).
/// <summary>
/// Finds whether the specified application name is configured in the system environment.
/// If it exists, return the full path, otherwise return null
/// </summary>
public static string FindExeInPath(string exeName)
{
// get environment variable "Path" value
var pathVariable = Environment.GetEnvironmentVariable("PATH");
// Split string
string[] paths = pathVariable.Split(Path.PathSeparator);
foreach (string path in paths)
{
string fullPath = Path.Combine(path, exeName);
if (File.Exists(fullPath))
{
return fullPath;
}
}
return null;
}
/// <summary>
///Startup program Specifies a program, enters a program name, and determines whether the program is running.
/// If it is running, exit directly, otherwise run the program according to the input path.
/// </summary>
public static void CheckStartProcess(string processPath)
{
string processName = Path.GetFileName(processPath);
CheckStartProcess(processName, processPath);
}
/// <summary>
/// Startup program Specifies a program, enters a program name, and determines whether the program is running.
/// If it is running, exit directly, otherwise run the program according to the input path.
/// </summary>
public static void CheckStartProcess(string processName, string processPath)
{
// Check whather the program is running
if (!IsProcessRunning(processName))
{
Console.WriteLine($"{processName} is not running. Starting the process...");
StartProcess(processPath);
}
else Console.WriteLine($"{processName} is already running.");
}
/// <summary>
/// Enter the program path to start the program
/// </summary>
public static void StartProcess(string processPath)
{
try
{
Process.Start(processPath);
Console.WriteLine("Process started successfully.");
}
catch (Exception ex)
{
Console.WriteLine($"Error starting process: {ex.Message}");
}
}
/// <summary>
/// Check whather the process is running
/// </summary>
public static bool IsProcessRunning(string processName)
{
Process[] processes = Process.GetProcessesByName(processName);
return processes.Length > 0;
}
/// <summary>
/// close the process with the specify name.
/// </summary>
/// <param name="processName"></param>
public static void CloseProcess(string processName)
{
try
{
foreach (var process in Process.GetProcessesByName(processName))
{
process.Kill();
process.WaitForExit();
Application.Current.Shutdown();
}
}
catch (Exception ex)
{
MessageBox.Show($"无法关闭【{processName}】进程: {ex.Message}");
}
}
/// <summary>
/// get current process name
/// </summary>
public static string GetProgramName()
{
Assembly assembly = Assembly.GetExecutingAssembly();
return assembly.GetName().Name;
}
#endregion
#region File save
/// <summary>
/// Save record
/// </summary>
public void WriteDataToFileAsync(string data, int retryCount = 5, int delayMilliseconds = 500)
{
//Get the directory where the file located.
string directoryPath = Path.GetDirectoryName(CurrentPath);
// if directory exists't ,create directory(include all must directory).
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
}
for (int i = 0; i < retryCount; i++)
{
try
{
using (FileStream fs = new FileStream(CurrentPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8))
{
writer.WriteAsync(data);
}
return; // successful writed exit the loop.
}
catch (IOException ex)
{
if (i == retryCount - 1)
{
throw; //If the maximum number of retries is reached , a exception is thrown
}
Task.Delay(delayMilliseconds); // Wait a while and try again
}
catch (Exception ex)
{
throw; //other exception is thrown
}
}
}
#endregion
}
}