diff --git a/AIAssistant/Model.cs b/AIAssistant/Model.cs new file mode 100644 index 0000000..d1d9ca1 --- /dev/null +++ b/AIAssistant/Model.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CSharpToJsonSchema; +using Ollama; +using RhythmBase.Components; +using System.ComponentModel; + +namespace RDTKEditor.AIAssistant +{ + public class Assistant + { + public const string Deepseek = "deepseek-r1:8b"; + public const string Smollm = "smollm2:135m"; + public const string Qwen_0_5 = "qwen2.5-coder:0.5b"; + public const string Qwen_3 = "qwen2.5-coder:3b"; + public OllamaApiClient Ollama { get; } = new(baseUri: new Uri("http://127.0.0.1:11434/api")); + public Chat Chat { get; } + public Assistant(string modelName) + { + Chat = Ollama.Chat( + model: modelName, + autoCallTools: true + ); + var utils = new RhythmBaseUtils(); + Chat.AddToolService(utils.AsTools().AsOllamaTools(), utils.AsCalls()); + } + public async IAsyncEnumerable GetResponse(string modelName, string userInput) + { + await foreach (var responce in Ollama.Completions.GenerateCompletionAsync(modelName, userInput)) + { + if (responce != null) + { + yield return responce; + } + } + } + } + [GenerateJsonSchema] + public interface IRhythmBaseUtils + { + [Description("创建空关卡")] + public void CreateEmptyLevel(); + [Description("创建关卡模板(默认关卡)")] + public void CreateLevelTemplate(); + [Description("打开关卡")] + public void OpenLevel([Description("关卡路径")] string filepath); + [Description("添加轨道")] + public void AddRow( + [Description("轨道所在的房间")] RDRoomIndex roomIndex, + [Description("轨道名称")] string trackName + ); + [Description("保存关卡")] + public void SaveLevel([Description("关卡路径,后缀为 .rdlevel")] string filepath); + } + public class RhythmBaseUtils : IRhythmBaseUtils + { + private RDLevel? level; + public void CreateEmptyLevel() + { + Console.BackgroundColor = ConsoleColor.Green; + Console.WriteLine($"Called CreateEmptyLevel"); + Console.ResetColor(); + level = []; + } + public void CreateLevelTemplate() + { + Console.BackgroundColor = ConsoleColor.Green; + Console.WriteLine($"Called CreateLevelTemplate"); + Console.ResetColor(); + level = RDLevel.Default; + } + public void OpenLevel(string filepath) + { + Console.BackgroundColor = ConsoleColor.Green; + Console.WriteLine($"Called OpenLevel: {filepath}"); + Console.ResetColor(); + level = RDLevel.Read(filepath); + } + public void AddRow(RDRoomIndex roomIndex, string trackName) + { + Console.BackgroundColor = ConsoleColor.Green; + Console.WriteLine($"Called AddRow: [{roomIndex}] {trackName}"); + Console.ResetColor(); + level?.CreateRow(roomIndex, trackName); + } + public void SaveLevel(string filepath) + { + Console.BackgroundColor = ConsoleColor.Green; + Console.WriteLine($"Called SaveLevel: {filepath}"); + Console.ResetColor(); + string dir = Path.GetDirectoryName(filepath) ?? ""; + if (!string.IsNullOrEmpty(dir)) + { + Directory.CreateDirectory(dir); + } + level?.Write(filepath); + } + } +} diff --git a/MainWindow.xaml b/MainWindow.xaml index bcccf7a..6cbc7ed 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -96,7 +96,6 @@ - diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index f9d166e..843a193 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -1,10 +1,11 @@ using Microsoft.Win32; +using Ollama; +using RDTKEditor.AIAssistant; using RDTKEditor.Models; using RhythmBase.Events; using SkiaSharp; using SkiaSharp.Views.Desktop; using System.ComponentModel; -using System.Diagnostics; using System.Reflection; using System.Windows; using System.Windows.Controls; @@ -17,6 +18,7 @@ namespace RDTKEditor /// public partial class MainWindow : Window { + private Assistant Assistant = new(Assistant.Qwen_3); private SKSizeI _vsScale = new(1600,900); private readonly RDTKView viewModel = new(); /*public MainWindow() @@ -260,6 +262,17 @@ namespace RDTKEditor }); } + private async void AIAssistantButton_Click(object sender, RoutedEventArgs e) + { + string input = AIAssistantText.Text; + if (string.IsNullOrEmpty(input)) + return; + Message responce = await Assistant.Chat.SendAsync(input); + AIAssistantText.Text = responce.Content; + } + } + public class MainViewModel : INotifyPropertyChanged + private void CheckBox_Checked(object sender, RoutedEventArgs e) { MessageBox.Show("已确认"); diff --git a/RDTKEditor.csproj b/RDTKEditor.csproj index 875c821..8a08df3 100644 --- a/RDTKEditor.csproj +++ b/RDTKEditor.csproj @@ -10,6 +10,7 @@ +