Skip to content

Commit dd4c992

Browse files
committed
Bump version
1 parent cc3fbb9 commit dd4c992

File tree

13 files changed

+471
-497
lines changed

13 files changed

+471
-497
lines changed

CommonUtils.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Net.Http;
34
using System.Windows.Forms;
45
using Microsoft.Office.Interop.Word;
56
using Word = Microsoft.Office.Interop.Word;
@@ -8,6 +9,8 @@ namespace TextForge
89
{
910
internal class CommonUtils
1011
{
12+
public static readonly HttpClient client = new HttpClient();
13+
1114
public static void DisplayError(Exception ex)
1215
{
1316
MessageBox.Show(ex.Message, ex.GetType().Name, MessageBoxButtons.OK, MessageBoxIcon.Error);

Forge.cs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public partial class Forge
2525

2626
private CustomTaskPane _generateTaskPane;
2727
private CustomTaskPane _ragControlTaskPane;
28+
29+
private static readonly object door = new object();
2830

2931
private void Forge_Load(object sender, RibbonUIEventArgs e)
3032
{
@@ -33,11 +35,11 @@ private void Forge_Load(object sender, RibbonUIEventArgs e)
3335
if (!ThisAddIn.IsAddinInitialized)
3436
ThisAddIn.InitializeAddin();
3537

36-
List<string> models = new List<string>(ThisAddIn.ModelList);
38+
List<string> modelList = new List<string>(ModelProperties.GetModelList(ThisAddIn.ModelList));
3739

3840
// Remove embedding models from the list
39-
RemoveEmbeddingModels(ref models);
40-
AddEmbeddingModelsToDropDownList(models);
41+
modelList = RemoveEmbeddingModels(modelList).ToList();
42+
AddEmbeddingModelsToDropDownList(modelList);
4143

4244
_box = new AboutBox();
4345
_optionsBox = this.OptionsGroup;
@@ -50,33 +52,29 @@ private void Forge_Load(object sender, RibbonUIEventArgs e)
5052
}
5153
}
5254

53-
private void RemoveEmbeddingModels(ref List<string> modelList)
55+
private IEnumerable<string> RemoveEmbeddingModels(IEnumerable<string> modelList)
5456
{
55-
var copyList = new List<string>(modelList);
56-
foreach (var model in copyList)
57-
{
58-
foreach (var item in ModelProperties.UniqueEmbedModels)
59-
if (model.Contains(item))
60-
modelList.Remove(model);
61-
if (model.Contains("embed"))
62-
modelList.Remove(model);
63-
}
57+
return modelList
58+
.Where(model => !ModelProperties.UniqueEmbedModels.Any(item => model.Contains(item)) && !model.Contains("embed"))
59+
.ToList();
6460
}
6561

66-
private void AddEmbeddingModelsToDropDownList(List<string> models)
62+
private void AddEmbeddingModelsToDropDownList(IEnumerable<string> models)
6763
{
6864
var ribbonFactory = Globals.Factory.GetRibbonFactory();
69-
foreach (string model in models)
65+
var sortedModels = models.OrderBy(m => m).ToList();
66+
foreach (string model in sortedModels)
7067
{
71-
var newItem = ribbonFactory.CreateRibbonDropDownItem();
72-
newItem.Label = model;
73-
74-
ModelListDropDown.Items.Add(newItem);
75-
76-
if (model == ThisAddIn.Model)
7768
{
78-
ModelListDropDown.SelectedItem = newItem;
79-
UpdateCheckbox();
69+
var newItem = ribbonFactory.CreateRibbonDropDownItem();
70+
newItem.Label = model;
71+
ModelListDropDown.Items.Add(newItem);
72+
73+
if (model == ThisAddIn.Model)
74+
{
75+
ModelListDropDown.SelectedItem = newItem;
76+
UpdateCheckbox();
77+
}
8078
}
8179
}
8280
}
@@ -92,13 +90,16 @@ private void GenerateButton_Click(object sender, RibbonControlEventArgs e)
9290
}
9391
}
9492

95-
private void ModelListDropDown_SelectionChanged(object sender, RibbonControlEventArgs e)
93+
private async void ModelListDropDown_SelectionChanged(object sender, RibbonControlEventArgs e)
9694
{
9795
try
9896
{
99-
ThisAddIn.Model = GetSelectedItemLabel();
100-
ThisAddIn.ContextLength = ModelProperties.GetContextLength(ThisAddIn.Model);
101-
UpdateCheckbox();
97+
await Task.Run(() =>
98+
{
99+
ThisAddIn.Model = GetSelectedItemLabel();
100+
ThisAddIn.ContextLength = ModelProperties.GetContextLength(ThisAddIn.Model, ThisAddIn.ModelList);
101+
UpdateCheckbox();
102+
});
102103
}
103104
catch (Exception ex)
104105
{

ModelProperties.cs

Lines changed: 68 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Text.Json.Nodes;
5+
using System.Text.Json;
46
using OpenAI.Models;
7+
using System.Diagnostics;
58

69
namespace TextForge
710
{
@@ -27,136 +30,43 @@ internal class ModelProperties
2730
{ "gpt-3.5-turbo-instruct", 4096 },
2831
};
2932

30-
private static readonly Dictionary<string, int> ollamaModelsContextLength = new Dictionary<string, int>()
31-
{
32-
{ "llama3.1", 131072 },
33-
{ "gemma2", 8192 },
34-
{ "mistral-nemo", 1024000 },
35-
{ "mistral-large", 32768 },
36-
{ "qwen2", 32768 },
37-
{ "deepseek-coder-v2", 163840 },
38-
{ "phi3", 4096 }, // the lowest config of phi3 (https://ollama.com/library/phi3:medium-4k/blobs/0d98d611d31b)
39-
{ "mistral", 32768 },
40-
{ "mixtral", 32768 },
41-
{ "codegemma", 8192 },
42-
{ "command-r", 131072 },
43-
{ "command-r-plus", 131072 },
44-
{ "llava", 4096 }, // https://ollama.com/library/llava:13b-v1.6-vicuna-q4_0/blobs/87d5b13e5157
45-
{ "llama3", 8192 },
46-
{ "gemma", 8192 },
47-
{ "qwen", 32768 },
48-
{ "llama2", 4096 },
49-
{ "codellama", 16384 },
50-
{ "dolphin-mixtral", 32768 },
51-
{ "phi", 2048 },
52-
{ "llama2-uncensored", 2048 },
53-
{ "deepseek-coder", 16384 },
54-
{ "dolphin-mistral", 32768 },
55-
{ "zephyr", 32768 },
56-
{ "starcoder2", 16384 },
57-
{ "dolphin-llama3", 8192 },
58-
{ "orca-mini", 2048 },
59-
{ "yi", 4096 },
60-
{ "mistral-openorca", 32768 },
61-
{ "llava-llama3", 8192 },
62-
{ "starcoder", 8192 },
63-
{ "llama2-chinese", 4096 },
64-
{ "vicuna", 2048 }, // https://ollama.com/library/vicuna:7b-q3_K_S/blobs/a887a7755a1e
65-
{ "tinyllama", 2048 },
66-
{ "codestral", 32768 },
67-
{ "wizard-vicuna-uncensored", 2048 },
68-
{ "nous-hermes2", 4096 },
69-
{ "openchat", 8192 },
70-
{ "aya", 8192 },
71-
{ "granite-code", 2048 },
72-
{ "wizardlm2", 32768 },
73-
{ "tinydolphin", 4096 },
74-
{ "wizardcoder", 16384 },
75-
{ "stable-code", 16384 },
76-
{ "openhermes", 32768 },
77-
{ "codeqwen", 65536 },
78-
{ "codegeex4", 131072 },
79-
{ "stablelm2", 4096 },
80-
{ "wizard-math", 2048 }, // https://ollama.com/library/wizard-math:7b-q5_1/blobs/b39818bfe610
81-
{ "qwen2-math", 4096 },
82-
{ "neural-chat", 32768 },
83-
{ "llama3-gradient", 1048576 },
84-
{ "phind-codellama", 16384 },
85-
{ "nous-hermes", 2048 }, // https://ollama.com/library/nous-hermes:13b-q4_1/blobs/433b4abded9b
86-
{ "sqlcoder", 8192 }, // https://ollama.com/library/sqlcoder:15b-q8_0/blobs/2319eec9425f
87-
{ "dolphincoder", 16384 },
88-
{ "xwinlm", 4096 },
89-
{ "deepseek-llm", 4096 },
90-
{ "yarn-llama2", 65536 },
91-
{ "llama3-chatqa", 8192 },
92-
{ "wizardlm", 2048 },
93-
{ "starling-lm", 8192 },
94-
{ "falcon", 2048 },
95-
{ "orca2", 4096 },
96-
{ "moondream", 2048 },
97-
{ "samantha-mistral", 32768 },
98-
{ "solar", 4096 },
99-
{ "smollm", 2048 },
100-
{ "stable-beluga", 4096 },
101-
{ "dolphin-phi", 2048 },
102-
{ "deepseek-v2", 163840 },
103-
{ "glm4", 8192 }, // https://ollama.com/library/glm4:9b-text-q6_K/blobs/2f657a57a8df
104-
{ "phi3.5", 131072 },
105-
{ "bakllava", 32768 },
106-
{ "wizardlm-uncensored", 4096 },
107-
{ "yarn-mistral", 32768 }, // https://ollama.com/library/yarn-mistral/blobs/0e8703041ff2
108-
{ "medllama2", 4096 },
109-
{ "llama-pro", 4096 },
110-
{ "llava-phi3", 4096 },
111-
{ "meditron", 2048 },
112-
{ "nous-hermes2-mixtral", 32768 },
113-
{ "nexusraven", 16384 },
114-
{ "hermes3", 131072 },
115-
{ "codeup", 4096 },
116-
{ "everythinglm", 16384 },
117-
{ "internlm2", 32768 },
118-
{ "magicoder", 16384 },
119-
{ "stablelm-zephyr", 4096 },
120-
{ "codebooga", 16384 },
121-
{ "yi-coder", 131072 },
122-
{ "mistrallite", 32768 },
123-
{ "llama3-groq-tool-use", 8192 },
124-
{ "falcon2", 2048 },
125-
{ "wizard-vicuna", 2048 },
126-
{ "duckdb-nsql", 16384 },
127-
{ "megadolphin", 4096 },
128-
{ "reflection", 8192 },
129-
{ "notux", 32768 },
130-
{ "goliath", 4096 },
131-
{ "open-orca-platypus2", 4096 },
132-
{ "notus", 32768 },
133-
{ "dbrx", 32768 },
134-
{ "mathstral", 32768 },
135-
{ "alfred", 2048 },
136-
{ "nuextract", 4096 },
137-
{ "firefunction-v2", 8192 },
138-
{ "deepseek-v2.5", 163840 },
139-
// new models
140-
{ "minicpm-v", 32768 },
141-
{ "reader-lm", 256000 },
142-
{ "mistral-small", 131072 },
143-
{ "bespoke-minicheck", 32768 },
144-
{ "qwen2.5", 32768 },
145-
{ "nemotron-mini", 4096 },
146-
{ "solar-pro", 4096 },
147-
{ "qwen2.5-coder", 32768 }
148-
};
33+
private static bool IsOllamaEndpoint = false;
34+
private static bool IsOllamaFetched = false;
35+
private static Dictionary<string, int> ollamaContextWindowCache = new Dictionary<string, int>();
14936

150-
public static int GetContextLength(string modelName)
37+
public static int GetContextLength(string modelName, OpenAIModelCollection availableModels)
15138
{
15239
if (openAIModelsContextLength.ContainsKey(modelName))
15340
{
15441
return openAIModelsContextLength[modelName];
15542
}
15643
else if (modelName.Contains(':'))
15744
{
158-
string key = modelName.Split(':')[0];
159-
return ollamaModelsContextLength.ContainsKey(key) ? ollamaModelsContextLength[key] : BaselineContextWindowLength;
45+
try
46+
{
47+
if (!IsOllamaFetched)
48+
{
49+
IsOllamaEndpoint = IsOllama(availableModels);
50+
IsOllamaFetched = true;
51+
}
52+
if (IsOllamaEndpoint)
53+
{
54+
int contextWindow;
55+
if (!ollamaContextWindowCache.TryGetValue(modelName, out contextWindow))
56+
{
57+
contextWindow = GetOllamaModelContextWindow(modelName);
58+
ollamaContextWindowCache[modelName] = contextWindow;
59+
}
60+
return contextWindow;
61+
} else
62+
{
63+
return BaselineContextWindowLength;
64+
}
65+
} catch (OllamaMissingContextWindowException ex)
66+
{
67+
CommonUtils.DisplayWarning(ex);
68+
return BaselineContextWindowLength;
69+
}
16070
}
16171
else if (modelName.StartsWith("o1"))
16272
{
@@ -184,10 +94,44 @@ public static int GetContextLength(string modelName)
18494
}
18595
}
18696

187-
public static IEnumerable<string> GetModelList(ModelClient client)
97+
public static IEnumerable<string> GetModelList(OpenAIModelCollection availableModels)
18898
{
189-
OpenAIModelInfoCollection availableModels = client.GetModels().Value;
19099
return availableModels.Select(info => info.Id).ToList();
191100
}
101+
102+
private static bool IsOllama(OpenAIModelCollection availableModels)
103+
{
104+
return (availableModels.Count == 0) ? false : availableModels.First().OwnedBy == "library";
105+
}
106+
107+
private static int GetOllamaModelContextWindow(string model)
108+
{
109+
var ollamaEndpoint = ThisAddIn.OpenAIEndpoint.Replace("/v1", "");
110+
111+
Ollama ollamaInstance = new Ollama(new Uri(ollamaEndpoint));
112+
var dict = ollamaInstance.Show(model, true).Result; // or await, if Show() is async
113+
114+
// Navigate to "model_info"
115+
if (dict.TryGetValue("model_info", out var modelInfoObj) && modelInfoObj is JsonElement modelInfoElement)
116+
{
117+
// Use JsonNode or JsonElement to search for "context_length" key
118+
var modelInfoNode = JsonNode.Parse(modelInfoElement.GetRawText());
119+
120+
foreach (var keyValuePair in modelInfoNode.AsObject())
121+
{
122+
// Search for a nested object containing "context_length"
123+
if (keyValuePair.Key.EndsWith(".context_length"))
124+
{
125+
return int.Parse(keyValuePair.Value.ToString());
126+
}
127+
}
128+
}
129+
throw new OllamaMissingContextWindowException($"Unable to fetch the context length for {model}!");
130+
}
131+
}
132+
133+
public class OllamaMissingContextWindowException : ApplicationException
134+
{
135+
public OllamaMissingContextWindowException(string message) : base(message) { }
192136
}
193137
}

0 commit comments

Comments
 (0)