Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
fdc53bf
WIP
amakropoulos Aug 13, 2025
bda6dff
Merge fdc53bf9e7b72d3ed871bf9d9a4fae8a09e50340 into 891497bf8ad6d10f9…
amakropoulos Aug 13, 2025
0f94f6f
update VERSION
amakropoulos Aug 13, 2025
728babc
working setup
amakropoulos Aug 15, 2025
ddc67c6
fix platform paths on postprocess
amakropoulos Aug 15, 2025
ff1afde
initial working LLM with LlamaLib
amakropoulos Aug 15, 2025
00a76ec
add NewtonSoft JSON dependency
amakropoulos Aug 15, 2025
bd1ec6d
add LlamaLib
amakropoulos Aug 15, 2025
bc74831
implementation of LLMAgent methods (untested)
amakropoulos Aug 15, 2025
8118aa5
allow empty templates
amakropoulos Aug 17, 2025
05caeea
small fixes mainly on the ChatAsync
amakropoulos Aug 17, 2025
23282d4
use ChatAsync instead of Chat
amakropoulos Aug 17, 2025
8762162
move completion parameters to LLMCaller
amakropoulos Aug 18, 2025
42ae20f
rename LLMCaller to LLMClient
amakropoulos Aug 18, 2025
5c62cec
simplify grammar by keeping the grammar value instead of the file
amakropoulos Aug 18, 2025
f778fb9
remove unused completion parameters
amakropoulos Aug 18, 2025
567ad3f
getters/setters for variables needing more actions
amakropoulos Aug 18, 2025
958f8b9
remove not needed classes
amakropoulos Aug 18, 2025
2614d20
general improvements and small fixes
amakropoulos Aug 19, 2025
18d1d1b
more changes
amakropoulos Aug 19, 2025
8f7f869
more improvements
amakropoulos Aug 19, 2025
c715ccf
check callback target for destruction
amakropoulos Aug 20, 2025
b9e9464
initial pass of basic unit test
amakropoulos Nov 11, 2025
116e41e
update to latest LlamaLib (remote changes)
amakropoulos Nov 13, 2025
548820b
simplify library finding
amakropoulos Nov 13, 2025
1425189
small fixes
amakropoulos Nov 13, 2025
9d75920
fix llmagent save test
amakropoulos Nov 17, 2025
6be3137
autosave history
amakropoulos Nov 18, 2025
7d27df9
fix blas selection with exclusion list
amakropoulos Nov 18, 2025
68412f6
adapt for chat history removal of system prompt
amakropoulos Nov 18, 2025
ea13827
functionality to return and show the service command
amakropoulos Nov 18, 2025
35804a6
remove chat template tests
amakropoulos Nov 18, 2025
84ecfc1
remove template functionality
amakropoulos Dec 2, 2025
f11d0ba
Option to debug the LLM prompts
amakropoulos Dec 2, 2025
2cf2e41
show grammar with box
amakropoulos Dec 2, 2025
556e63e
comment typo
amakropoulos Dec 2, 2025
9250efd
remove save cache functionality
amakropoulos Dec 2, 2025
7726186
adapt tests to recent changes
amakropoulos Dec 2, 2025
ed276ca
update Samples to v3
amakropoulos Dec 2, 2025
84efdf7
fix setting up of functions dependent on caller object
amakropoulos Dec 2, 2025
f08e89a
Add undream libraries in macOS Xcode
amakropoulos Dec 5, 2025
1c4c701
update tooltips
amakropoulos Dec 5, 2025
ec01c69
fix: Bypasses the issue where errors occur due to antivirus program d…
Nov 21, 2025
750c06a
Add migration guide
amakropoulos Dec 8, 2025
5613738
await rag.Add
amakropoulos Dec 8, 2025
7328049
retain loras in Editor
amakropoulos Dec 9, 2025
73a8556
work around async warning
amakropoulos Dec 9, 2025
9db50a4
use LLMUnity exceptions alongside an error log
amakropoulos Dec 10, 2025
a24c721
update Readme
amakropoulos Dec 10, 2025
12924ff
fix typos
amakropoulos Dec 10, 2025
c6b1647
update LlamaLib
amakropoulos Dec 11, 2025
2930ddd
try-catch in Chat
amakropoulos Dec 11, 2025
95f000d
update LlamaLib
amakropoulos Dec 11, 2025
bcd67aa
remove user and assistant roles
amakropoulos Dec 11, 2025
7857ebd
fix usearch for iOS
amakropoulos Jul 17, 2025
1e4aa40
update tooltips
amakropoulos Dec 12, 2025
b5900c8
update tests
amakropoulos Dec 12, 2025
c536a62
implement changes for IL2CPP
amakropoulos Dec 16, 2025
60dd270
fix build location for Android
amakropoulos Dec 16, 2025
cf2bcb7
adapt Readme
amakropoulos Dec 16, 2025
e58836d
update LlamaLib
amakropoulos Dec 16, 2025
73ad540
update LlamaLib
amakropoulos Dec 16, 2025
09a1728
set debug level before creating LlamaLib
amakropoulos Dec 16, 2025
e2e66c8
build usearch for Android 16kb support
amakropoulos Dec 16, 2025
3ce0451
serialize embedding fields
amakropoulos Dec 17, 2025
a741e63
update LlamaLib API
amakropoulos Dec 23, 2025
0b1d1b9
update tests
amakropoulos Dec 23, 2025
8436724
use internal debug prompt
amakropoulos Dec 23, 2025
3855ab5
update license
amakropoulos Dec 23, 2025
102eb53
show server architecture in the command
amakropoulos Dec 23, 2025
b60de0e
update LlamaLib
amakropoulos Jan 6, 2026
5af2577
move tests to Editor instead of Runtime, adapt tests for windows
amakropoulos Jan 6, 2026
9f409e1
fix and polish samples
amakropoulos Jan 7, 2026
fc3b214
check for null before competion
amakropoulos Jan 8, 2026
06da6c5
auto-indentation
amakropoulos Jan 8, 2026
e865b10
bring back the legacy input / event system
amakropoulos Jan 8, 2026
615279e
adapt unit tests
amakropoulos Jan 8, 2026
11ecc69
implement auto-setup of EventSystem for both legacy and latest Unity …
amakropoulos Jan 8, 2026
fbf0aa9
handle both input systems at the same time
amakropoulos Jan 8, 2026
004ff0f
remove secondar contentSizeFitter
amakropoulos Jan 8, 2026
ada88cf
show error if a LLM is used for embedding
amakropoulos Jan 8, 2026
1937328
update Windows unit tests
amakropoulos Jan 8, 2026
913a98d
remove exit button from mobile demo
amakropoulos Jan 8, 2026
4cf6e69
use __Internal only in iOS Player
amakropoulos Jan 10, 2026
05c8b21
fix iOS/visionOS plugin filenames
amakropoulos Jan 10, 2026
593c9b4
get processor type outside async
amakropoulos Jan 10, 2026
d576373
add search paths to xcode project
amakropoulos Jan 12, 2026
25202be
add cublas toggle in setup settings
amakropoulos Jan 12, 2026
0ebe145
add cublas toggle only in LLM
amakropoulos Jan 12, 2026
827961a
add logo
amakropoulos Jan 12, 2026
09eb29b
select (down)loaded model
amakropoulos Jan 12, 2026
e68192a
add logo meta
amakropoulos Jan 12, 2026
ef2eca2
update images
amakropoulos Jan 12, 2026
7abb5df
remove redundant variables
amakropoulos Jan 12, 2026
fc1d441
fix update tooltips script and update them
amakropoulos Jan 12, 2026
fd76b9c
update readme
amakropoulos Jan 12, 2026
e691523
guard VisionOS for Unity 2021 compatibility
amakropoulos Jan 12, 2026
9bde194
add gemma-embedding to embedding architectures
amakropoulos Jan 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/doxygen/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ PROJECT_NAME = "LLM for Unity"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = v2.5.2
PROJECT_NUMBER = v3.0.0

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
22 changes: 5 additions & 17 deletions Editor/LLMCallerEditor.cs → Editor/LLMClientEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

namespace LLMUnity
{
[CustomEditor(typeof(LLMCaller), true)]
[CustomEditor(typeof(LLMClient), true)]
public class LLMCallerEditor : PropertyEditor {}

[CustomEditor(typeof(LLMCharacter), true)]
public class LLMCharacterEditor : LLMCallerEditor
[CustomEditor(typeof(LLMAgent), true)]
public class LLMAgentEditor : LLMCallerEditor
{
public override void AddModelSettings(SerializedObject llmScriptSO)
{
Expand All @@ -23,26 +23,14 @@ public override void AddModelSettings(SerializedObject llmScriptSO)
ShowPropertiesOfClass("", llmScriptSO, new List<Type> { typeof(ModelAttribute) }, false);

EditorGUILayout.BeginHorizontal();
GUILayout.Label("Grammar", GUILayout.Width(EditorGUIUtility.labelWidth));
if (GUILayout.Button("Load grammar", GUILayout.Width(buttonWidth)))
{
EditorApplication.delayCall += () =>
{
string path = EditorUtility.OpenFilePanelWithFilters("Select a gbnf grammar file", "", new string[] { "Grammar Files", "gbnf" });
string path = EditorUtility.OpenFilePanelWithFilters("Select a gbnf grammar file", "", new string[] { "Grammar Files", "json,gbnf" });
if (!string.IsNullOrEmpty(path))
{
((LLMCharacter)target).SetGrammar(path);
}
};
}
if (GUILayout.Button("Load JSON grammar", GUILayout.Width(buttonWidth)))
{
EditorApplication.delayCall += () =>
{
string path = EditorUtility.OpenFilePanelWithFilters("Select a json schema grammar file", "", new string[] { "Grammar Files", "json" });
if (!string.IsNullOrEmpty(path))
{
((LLMCharacter)target).SetJSONGrammar(path);
((LLMAgent)target).LoadGrammar(path);
}
};
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 16 additions & 41 deletions Editor/LLMEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,29 +44,17 @@ void AddSSLLoad(string type, Callback<string> setterCallback)
}
}

void AddSSLInfo(string propertyName, string type, Callback<string> setterCallback)
{
string path = llmScriptSO.FindProperty(propertyName).stringValue;
if (path != "")
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("SSL " + type + " path", path);
if (GUILayout.Button(trashIcon, GUILayout.Height(actionColumnWidth), GUILayout.Width(actionColumnWidth))) setterCallback("");
EditorGUILayout.EndHorizontal();
}
}

EditorGUILayout.LabelField("Server Security Settings", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(llmScriptSO.FindProperty("APIKey"));
EditorGUILayout.PropertyField(llmScriptSO.FindProperty("_APIKey"));

if (llmScriptSO.FindProperty("advancedOptions").boolValue)
{
EditorGUILayout.BeginHorizontal();
AddSSLLoad("certificate", llmScript.SetSSLCert);
AddSSLLoad("key", llmScript.SetSSLKey);
AddSSLLoad("certificate", llmScript.SetSSLCertFromFile);
AddSSLLoad("key", llmScript.SetSSLKeyFromFile);
EditorGUILayout.EndHorizontal();
AddSSLInfo("SSLCertPath", "certificate", llmScript.SetSSLCert);
AddSSLInfo("SSLKeyPath", "key", llmScript.SetSSLKey);
EditorGUILayout.PropertyField(llmScriptSO.FindProperty("_SSLCert"));
EditorGUILayout.PropertyField(llmScriptSO.FindProperty("_SSLKey"));
}
Space();
}
Expand Down Expand Up @@ -111,7 +99,7 @@ public override void AddModelSettings(SerializedObject llmScriptSO)
if (llmScriptSO.FindProperty("advancedOptions").boolValue)
{
attributeClasses.Add(typeof(ModelAdvancedAttribute));
if (LLMUnitySetup.FullLlamaLib) attributeClasses.Add(typeof(ModelExtrasAttribute));
attributeClasses.Add(typeof(ModelExtrasAttribute));
}
ShowPropertiesOfClass("", llmScriptSO, attributeClasses, false);
Space();
Expand All @@ -126,10 +114,10 @@ static void ResetModelOptions()
{
List<string> existingOptions = new List<string>();
foreach (ModelEntry entry in LLMManager.modelEntries) existingOptions.Add(entry.url);
modelOptions = new List<string>(){"Download model", "Custom URL"};
modelNames = new List<string>(){null, null};
modelURLs = new List<string>(){null, null};
modelLicenses = new List<string>(){null, null};
modelOptions = new List<string>() { "Download model", "Custom URL" };
modelNames = new List<string>() { null, null };
modelURLs = new List<string>() { null, null };
modelLicenses = new List<string>() { null, null };
foreach (var entry in LLMUnitySetup.modelOptions)
{
string category = entry.Key;
Expand All @@ -146,9 +134,9 @@ static void ResetModelOptions()

float[] GetColumnWidths(bool expandedView)
{
List<float> widths = new List<float>(){actionColumnWidth, nameColumnWidth, templateColumnWidth};
if (expandedView) widths.AddRange(new List<float>(){textColumnWidth, textColumnWidth});
widths.AddRange(new List<float>(){includeInBuildColumnWidth, actionColumnWidth});
List<float> widths = new List<float>() { actionColumnWidth, nameColumnWidth, templateColumnWidth };
if (expandedView) widths.AddRange(new List<float>() { textColumnWidth, textColumnWidth });
widths.AddRange(new List<float>() { includeInBuildColumnWidth, actionColumnWidth });
return widths.ToArray();
}

Expand Down Expand Up @@ -351,19 +339,6 @@ void OnEnable()

DrawCopyableLabel(nameRect, entry.label, entry.filename);

if (!entry.lora)
{
string[] templateDescriptions = ChatTemplate.templatesDescription.Keys.ToList().ToArray();
string[] templates = ChatTemplate.templatesDescription.Values.ToList().ToArray();
int templateIndex = Array.IndexOf(templates, entry.chatTemplate);
int newTemplateIndex = EditorGUI.Popup(templateRect, templateIndex, templateDescriptions);
if (newTemplateIndex != templateIndex)
{
LLMManager.SetTemplate(entry.filename, templates[newTemplateIndex]);
UpdateModels();
}
}

if (expandedView)
{
if (hasURL)
Expand Down Expand Up @@ -440,14 +415,14 @@ private void DrawCopyableLabel(Rect rect, string label, string text = "")

private void CopyToClipboard(string text)
{
TextEditor te = new TextEditor {text = text};
TextEditor te = new TextEditor { text = text };
te.SelectAll();
te.Copy();
}

public void AddExtrasToggle()
{
if (ToggleButton("Use extras", LLMUnitySetup.FullLlamaLib)) LLMUnitySetup.SetFullLlamaLib(!LLMUnitySetup.FullLlamaLib);
if (ToggleButton("Use cuBLAS", LLMUnitySetup.CUBLAS)) LLMUnitySetup.SetCUBLAS(!LLMUnitySetup.CUBLAS);
}

public override void AddOptionsToggles(SerializedObject llmScriptSO)
Expand Down Expand Up @@ -481,7 +456,7 @@ public override void OnInspectorGUI()

AddOptionsToggles(llmScriptSO);
AddSetupSettings(llmScriptSO);
if (llmScriptSO.FindProperty("remote").boolValue) AddSecuritySettings(llmScriptSO, llmScript);
if (llmScriptSO.FindProperty("_remote").boolValue) AddSecuritySettings(llmScriptSO, llmScript);
AddModelLoadersSettings(llmScriptSO, llmScript);
AddChatSettings(llmScriptSO);

Expand Down
2 changes: 1 addition & 1 deletion Editor/PropertyEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public virtual bool ToggleButton(string text, bool activated)
public virtual void AddSetupSettings(SerializedObject llmScriptSO)
{
List<Type> attributeClasses = new List<Type>(){typeof(LocalRemoteAttribute)};
SerializedProperty remoteProperty = llmScriptSO.FindProperty("remote");
SerializedProperty remoteProperty = llmScriptSO.FindProperty("_remote");
if (remoteProperty != null) attributeClasses.Add(remoteProperty.boolValue ? typeof(RemoteAttribute) : typeof(LocalAttribute));
attributeClasses.Add(typeof(LLMAttribute));
if (llmScriptSO.FindProperty("advancedOptions").boolValue)
Expand Down
12 changes: 6 additions & 6 deletions Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ If the user's GPU is not supported, the LLM will fall back to the CPU
- `Debug` select to log the output of the model in the Unity Editor
- <details><summary>Advanced options</summary>

- <details><summary><code>Parallel Prompts</code> number of prompts / slots that can happen in parallel (default: -1 = number of LLMCharacter objects). Note that the context size is divided among the slots.</summary> If you want to retain as much context for the LLM and don't need all the characters present at the same time, you can set this number and specify the slot for each LLMCharacter object.
e.g. Setting `Parallel Prompts` to 1 and slot 0 for all LLMCharacter objects will use the full context, but the entire prompt will need to be computed (no caching) whenever a LLMCharacter object is used for chat. </details>
- <details><summary><code>Parallel Prompts</code> number of prompts / slots that can happen in parallel (default: -1 = number of LLMAgent objects). Note that the context size is divided among the slots.</summary> If you want to retain as much context for the LLM and don't need all the characters present at the same time, you can set this number and specify the slot for each LLMAgent object.
e.g. Setting `Parallel Prompts` to 1 and slot 0 for all LLMAgent objects will use the full context, but the entire prompt will need to be computed (no caching) whenever a LLMAgent object is used for chat. </details>
- `Dont Destroy On Load` select to not destroy the LLM GameObject when loading a new Scene

</details>

## Server Security Settings

- `API key` API key to use to allow access to requests from LLMCharacter objects (if `Remote` is set)
- `API key` API key to use to allow access to requests from LLMAgent objects (if `Remote` is set)
- <details><summary>Advanced options</summary>

- `Load SSL certificate` allows to load a SSL certificate for end-to-end encryption of requests (if `Remote` is set). Requires SSL key as well.
Expand Down Expand Up @@ -58,15 +58,15 @@ If the user's GPU is not supported, the LLM will fall back to the CPU

</details>

## LLMCharacter Settings
## LLMAgent Settings

- `Show/Hide Advanced Options` Toggle to show/hide advanced options from below
- `Log Level` select how verbose the log messages are
- `Use extras` select to install and allow the use of extra features (flash attention and IQ quants)

## 💻 Setup Settings
<div>
<img width="300" src=".github/LLMCharacter_GameObject.png" align="right"/>
<img width="300" src=".github/LLMAgent_GameObject.png" align="right"/>
</div>

- `Remote` whether the LLM used is remote or local
Expand Down Expand Up @@ -113,4 +113,4 @@ If it is not selected, the full reply from the model is received in one go
- `N Probs`: if greater than 0, the response also contains the probabilities of top N tokens for each generated token (default: 0)
- `Ignore Eos`: enable to ignore end of stream tokens and continue generating (default: false).

</details>
</details>
Loading