-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMyFunctions.cs
108 lines (99 loc) · 4.09 KB
/
MyFunctions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System.Text;
using ExcelDna.Documentation;
using ExcelDna.Integration;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
public static class MyFunctions
{
private static string DEFAULT_MODEL = "qwen2:1.5b-instruct-q4_K_M";
private static string SYSTEM_PROMPT = "You are a helpful assistant who loves numbers.";
[ExcelFunctionDoc(Description = "Generate a response from a LLM", HelpTopic = "Ask-LLM-AddIn.chm!1001")]
public static object ASK(
[ExcelArgument(Name = "prompt", Description = "a question/context for the LLM")]
string UserInput)
{
return ExcelAsyncUtil.Run(nameof(PostNetRequest), new object[] { UserInput }, () => PostNetRequest(UserInput));
}
[ExcelFunctionDoc(Description = "Interprets data with the help of a prompt", HelpTopic = "Ask-LLM-AddIn.chm!1002")]
public static object INTERPRET(
[ExcelArgument(Name = "prompt", Description = "context for the LLM")]
string Prompt,
[ExcelArgument(Name = "user_input", Description = "excel data that is appended to the prompt")]
object[,] UserInputs)
{
string ArrayRep = Prompt + ": ";
try
{
for (int i = 0; i < UserInputs.GetLength(0); i++)
{
ArrayRep += "[";
for (int j = 0; j < UserInputs.GetLength(1); j++)
{
string input = UserInputs[i, j].ToString() ?? throw new NullReferenceException("Excel input is null!");
if (input == "ExcelDna.Integration.ExcelEmpty")
{
input = "0";
}
ArrayRep += input;
ArrayRep += (j == UserInputs.GetLength(1) - 1) ? "" : ",";
}
ArrayRep += "], ";
}
if (ArrayRep.Contains(','))
{
ArrayRep = ArrayRep.Substring(0, ArrayRep.LastIndexOf(','));
}
}
catch (Exception e)
{
return "ERROR: " + e.Message;
}
return ExcelAsyncUtil.Run(nameof(PostNetRequest), new object[] { ArrayRep }, () => PostNetRequest(ArrayRep));
}
private static string PostNetRequest(string UserInput)
{
try
{
// Environment variable for the model
string? env = Environment.GetEnvironmentVariable("EXCEL_MODEL", EnvironmentVariableTarget.User);
if (env == null)
{
Environment.SetEnvironmentVariable("EXCEL_MODEL", DEFAULT_MODEL, EnvironmentVariableTarget.User);
env = DEFAULT_MODEL;
}
// Requires Ollama
var requestUrl = "http://localhost:11434/api/chat";
var requestPayload = new
{
model = env,
temperature = 0.0,
stream = false,
messages = new[]
{
new { role = "system", content = SYSTEM_PROMPT },
new { role = "user", content = UserInput }
}
};
using (var client = new HttpClient())
{
var requestContent = new StringContent(
JsonConvert.SerializeObject(requestPayload),
Encoding.UTF8,
"application/json");
var response = client.PostAsync(requestUrl, requestContent).Result;
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException($"HTTP request failed with status code {response.StatusCode}!");
}
var jsonResponse = response.Content.ReadAsStringAsync().Result;
var jsonObject = JObject.Parse(jsonResponse);
JToken Content = (jsonObject["message"] ?? throw new NullReferenceException("Cannot access \"message\" in JSON string"))["content"] ?? throw new NullReferenceException("Cannot access \"content\" in JSON string");
return Content.ToString();
}
}
catch (Exception e)
{
return "ERROR: " + e.Message;
}
}
}