新增托盘图标
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace Szmedi.RvKits.LLMScript
|
||||
{
|
||||
public class CodeExecutor
|
||||
{
|
||||
public void Execute(string methodBody, Autodesk.Revit.DB.Document doc, UIDocument uidoc)
|
||||
{
|
||||
string code = $@"
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI;
|
||||
using System;
|
||||
|
||||
public class ScriptRunner
|
||||
{{
|
||||
public void Run(Document doc, UIDocument uidoc)
|
||||
{{
|
||||
{methodBody}
|
||||
}}
|
||||
}}";
|
||||
|
||||
var syntaxTree = CSharpSyntaxTree.ParseText(code);
|
||||
|
||||
var compilation = CSharpCompilation.Create(
|
||||
"DynamicScript")
|
||||
.AddReferences(
|
||||
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
|
||||
MetadataReference.CreateFromFile(typeof(Document).Assembly.Location))
|
||||
.AddSyntaxTrees(syntaxTree)
|
||||
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
||||
|
||||
using var ms = new MemoryStream();
|
||||
var result = compilation.Emit(ms);
|
||||
|
||||
if (!result.Success)
|
||||
throw new Exception("Compilation failed");
|
||||
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
var assembly = Assembly.Load(ms.ToArray());
|
||||
|
||||
var type = assembly.GetType("ScriptRunner");
|
||||
var instance = Activator.CreateInstance(type);
|
||||
type.GetMethod("Run").Invoke(instance, new object[] { doc, uidoc });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Szmedi.RvKits.LLMScript
|
||||
{
|
||||
internal interface ILLMProvider
|
||||
{
|
||||
Task GenerateStreamAsync(string systemPrompt,
|
||||
string userPrompt,
|
||||
Action<string> onTokenReceived);
|
||||
}
|
||||
}
|
||||
40
ShrlAlgoToolkit.RevitAddins/General/LLMScript/LLMCmd.cs
Normal file
40
ShrlAlgoToolkit.RevitAddins/General/LLMScript/LLMCmd.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Text;
|
||||
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
namespace Szmedi.RvKits.LLMScript
|
||||
{
|
||||
/// <summary>
|
||||
/// Revit执行命令
|
||||
/// </summary>
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
[Regeneration(RegenerationOption.Manual)]
|
||||
public class LLMCmd : ExternalCommand
|
||||
{
|
||||
public async override void Execute()
|
||||
{
|
||||
string userTask = "将当前选中墙的Comments参数追加'检查'";
|
||||
|
||||
PromptManager promptManager = new PromptManager("Prompts/System_UltraStrict.txt");
|
||||
string systemPrompt = promptManager.GetSystemPrompt();
|
||||
string userPrompt = promptManager.BuildUserPrompt(userTask);
|
||||
|
||||
var llm = new OllamaProvider("http://localhost:11434/api/chat", "revit-coder");
|
||||
StringBuilder fullCode = new StringBuilder();
|
||||
|
||||
await llm.GenerateStreamAsync(
|
||||
systemPrompt,
|
||||
userPrompt,
|
||||
chunk =>
|
||||
{
|
||||
fullCode.Append(chunk);
|
||||
});
|
||||
CodeExecutor executor = new CodeExecutor();
|
||||
|
||||
executor.Execute(fullCode.ToString(), Document, UiDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Szmedi.RvKits.LLMScript
|
||||
{
|
||||
public class OllamaProvider : ILLMProvider
|
||||
{
|
||||
private static readonly HttpClient _client = new HttpClient();
|
||||
private readonly string _endpoint;
|
||||
private readonly string _model;
|
||||
|
||||
public OllamaProvider(string endpoint, string model)
|
||||
{
|
||||
_endpoint = endpoint;
|
||||
_model = model;
|
||||
}
|
||||
|
||||
public async Task GenerateStreamAsync(
|
||||
string systemPrompt,
|
||||
string userPrompt,
|
||||
Action<string> onTokenReceived)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
model = _model,
|
||||
messages = new[]
|
||||
{
|
||||
new { role = "system", content = systemPrompt },
|
||||
new { role = "user", content = userPrompt }
|
||||
},
|
||||
stream = true
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(payload);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, _endpoint);
|
||||
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await _client.SendAsync(
|
||||
request,
|
||||
HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
string line = await reader.ReadLineAsync();
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
JObject obj = JObject.Parse(line);
|
||||
|
||||
bool done = obj["done"]?.Value<bool>() ?? false;
|
||||
|
||||
var content = obj["message"]?["content"];
|
||||
if (content != null)
|
||||
{
|
||||
onTokenReceived(content.ToString());
|
||||
}
|
||||
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Szmedi.RvKits.LLMScript
|
||||
{
|
||||
public class OpenAiProvider : ILLMProvider
|
||||
{
|
||||
private static readonly HttpClient _client = new HttpClient();
|
||||
private readonly string _endpoint;
|
||||
private readonly string _apiKey;
|
||||
private readonly string _model;
|
||||
|
||||
public OpenAiProvider(string endpoint, string apiKey, string model)
|
||||
{
|
||||
_endpoint = endpoint;
|
||||
_apiKey = apiKey;
|
||||
_model = model;
|
||||
|
||||
_client.DefaultRequestHeaders.Clear();
|
||||
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
|
||||
}
|
||||
|
||||
public async Task GenerateStreamAsync(
|
||||
string systemPrompt,
|
||||
string userPrompt,
|
||||
Action<string> onTokenReceived)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
model = _model,
|
||||
messages = new[]
|
||||
{
|
||||
new { role = "system", content = systemPrompt },
|
||||
new { role = "user", content = userPrompt }
|
||||
},
|
||||
temperature = 0,
|
||||
stream = true
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(payload);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, _endpoint);
|
||||
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await _client.SendAsync(
|
||||
request,
|
||||
HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
string line = await reader.ReadLineAsync();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
if (!line.StartsWith("data:"))
|
||||
continue;
|
||||
|
||||
string data = line.Substring(5).Trim();
|
||||
|
||||
if (data == "[DONE]")
|
||||
break;
|
||||
|
||||
JObject obj = JObject.Parse(data);
|
||||
var delta = obj["choices"]?[0]?["delta"]?["content"];
|
||||
|
||||
if (delta != null)
|
||||
{
|
||||
onTokenReceived(delta.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Szmedi.RvKits.LLMScript
|
||||
{
|
||||
public class PromptManager
|
||||
{
|
||||
private readonly string _systemPrompt;
|
||||
|
||||
public PromptManager(string promptPath)
|
||||
{
|
||||
_systemPrompt = File.ReadAllText(promptPath);
|
||||
}
|
||||
|
||||
public string GetSystemPrompt()
|
||||
{
|
||||
return _systemPrompt;
|
||||
}
|
||||
|
||||
public string BuildUserPrompt(string task)
|
||||
{
|
||||
return task.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user