添加项目文件。
This commit is contained in:
298
ViewModels/ShareOllamaObject.cs
Normal file
298
ViewModels/ShareOllamaObject.cs
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user