Skip to content

Commit 97b2f05

Browse files
committed
UseNativeDebugger
1 parent 891497b commit 97b2f05

4 files changed

Lines changed: 80 additions & 9 deletions

File tree

Runtime/LLM.cs

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public class LLM : MonoBehaviour
3636
/// <summary> log the output of the LLM in the Unity Editor. </summary>
3737
[Tooltip("log the output of the LLM in the Unity Editor.")]
3838
[LLM] public bool debug = false;
39+
/// <summary> Wait for native debugger to connect to the backend </summary>
40+
[Tooltip("Wait for native debugger to connect to the backend")]
41+
[LLM] public bool UseNativeDebugger = false;
3942
/// <summary> number of prompts that can happen in parallel (-1 = number of LLMCaller objects) </summary>
4043
[Tooltip("number of prompts that can happen in parallel (-1 = number of LLMCaller objects)")]
4144
[LLMAdvanced] public int parallelPrompts = -1;
@@ -53,6 +56,8 @@ public class LLM : MonoBehaviour
5356
public bool started { get; protected set; } = false;
5457
/// <summary> Boolean set to true if the server has failed to start. </summary>
5558
public bool failed { get; protected set; } = false;
59+
/// <summary> Boolean set to true if the server has been destroyed. </summary>
60+
public bool destroyed { get; protected set; } = false;
5661
/// <summary> Boolean set to true if the models were not downloaded successfully. </summary>
5762
public static bool modelSetupFailed { get; protected set; } = false;
5863
/// <summary> Boolean set to true if the server has started and is ready to receive requests, false otherwise. </summary>
@@ -127,6 +132,13 @@ void OnValidate()
127132
public async void Awake()
128133
{
129134
if (!enabled) return;
135+
Load();
136+
}
137+
138+
public async Awaitable Load()
139+
{
140+
await Awaitable.BackgroundThreadAsync();
141+
130142
#if !UNITY_EDITOR
131143
modelSetupFailed = !await LLMManager.Setup();
132144
#endif
@@ -142,9 +154,13 @@ public async void Awake()
142154
failed = true;
143155
return;
144156
}
145-
await Task.Run(() => StartLLMServer(arguments));
157+
await StartLLMServerAsync(arguments);
146158
if (!started) return;
147-
if (dontDestroyOnLoad) DontDestroyOnLoad(transform.root.gameObject);
159+
if (dontDestroyOnLoad)
160+
{
161+
await Awaitable.MainThreadAsync();
162+
DontDestroyOnLoad(transform.root.gameObject);
163+
}
148164
}
149165

150166
/// <summary>
@@ -476,10 +492,11 @@ private void StopLogging()
476492
DestroyStreamWrapper(logStreamWrapper);
477493
}
478494

479-
private void StartLLMServer(string arguments)
495+
private async Task StartLLMServerAsync(string arguments)
480496
{
481497
started = false;
482498
failed = false;
499+
destroyed = false;
483500
bool useGPU = numGPULayers > 0;
484501

485502
foreach (string arch in LLMLib.PossibleArchitectures(useGPU))
@@ -488,6 +505,19 @@ private void StartLLMServer(string arguments)
488505
try
489506
{
490507
InitLib(arch);
508+
#if UNITY_EDITOR
509+
if (UseNativeDebugger)
510+
{
511+
if (llmlib?.LLM_IsDebuggerAttached == null)
512+
{
513+
LLMUnitySetup.Log($"Tried architecture: {arch} is not debug library");
514+
Destroy();
515+
continue;
516+
}
517+
518+
await WaitNativeDebug();
519+
}
520+
#endif
491521
InitService(arguments);
492522
LLMUnitySetup.Log($"Using architecture: {arch}");
493523
break;
@@ -504,6 +534,7 @@ private void StartLLMServer(string arguments)
504534
catch (Exception e)
505535
{
506536
error = $"{e.GetType()}: {e.Message}";
537+
Destroy();
507538
}
508539
LLMUnitySetup.Log($"Tried architecture: {arch}, error: " + error);
509540
}
@@ -514,20 +545,39 @@ private void StartLLMServer(string arguments)
514545
return;
515546
}
516547
CallWithLock(StartService);
517-
LLMUnitySetup.Log("LLM service created");
548+
if (started)
549+
LLMUnitySetup.Log("LLM service created");
518550
}
519551

520552
private void InitLib(string arch)
521553
{
522554
llmlib = new LLMLib(arch);
523-
CheckLLMStatus(false);
524555
}
525556

557+
#if UNITY_EDITOR
558+
private async Task WaitNativeDebug()
559+
{
560+
if (llmlib?.LLM_IsDebuggerAttached != null)
561+
{
562+
LLMUnitySetup.Log("waiting debugger");
563+
while (!destroyed)
564+
{
565+
if (llmlib.LLM_IsDebuggerAttached())
566+
{
567+
LLMUnitySetup.Log("remote debugger attached");
568+
break;
569+
}
570+
await Task.Delay(100);
571+
}
572+
}
573+
}
574+
#endif
575+
526576
void CallWithLock(EmptyCallback fn)
527577
{
528578
lock (startLock)
529579
{
530-
if (llmlib == null) throw new DestroyException();
580+
if (llmlib == null || destroyed) throw new DestroyException();
531581
fn();
532582
}
533583
}
@@ -556,9 +606,12 @@ private void StartService()
556606
{
557607
llmThread = new Thread(() => llmlib.LLM_Start(LLMObject));
558608
llmThread.Start();
559-
while (!llmlib.LLM_Started(LLMObject)) {}
560-
ApplyLoras();
561-
started = true;
609+
while (!llmlib.LLM_Started(LLMObject) && !destroyed) { }
610+
if (!destroyed)
611+
{
612+
ApplyLoras();
613+
started = true;
614+
}
562615
}
563616

564617
/// <summary>
@@ -611,6 +664,7 @@ void AssertStarted()
611664
string error = null;
612665
if (failed) error = "LLM service couldn't be created";
613666
else if (!started) error = "LLM service not started";
667+
else if (destroyed) error = "LLM service is being destroyed";
614668
if (error != null)
615669
{
616670
LLMUnitySetup.LogError(error);
@@ -807,6 +861,7 @@ public void CancelRequest(int id_slot)
807861
/// </summary>
808862
public void Destroy()
809863
{
864+
destroyed = true;
810865
lock (staticLock)
811866
lock (startLock)
812867
{

Runtime/LLMCaller.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ protected virtual async Task<Ret> PostRequestLocal<Res, Ret>(string json, string
238238
// send a post request to the server and call the relevant callbacks to convert the received content and handle it
239239
// this function has streaming functionality i.e. handles the answer while it is being received
240240
while (!llm.failed && !llm.started) await Task.Yield();
241+
if (llm.destroyed)
242+
return default;
241243
string callResult = null;
242244
switch (endpoint)
243245
{

Runtime/LLMCharacter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,8 @@ protected override async Task<Ret> PostRequestLocal<Res, Ret>(string json, strin
685685
if (endpoint != "completion") return await base.PostRequestLocal(json, endpoint, getContent, callback);
686686

687687
while (!llm.failed && !llm.started) await Task.Yield();
688+
if (llm.destroyed)
689+
return default;
688690

689691
string callResult = null;
690692
bool callbackCalled = false;

Runtime/LLMLib.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,12 @@ public LLMLib(string arch)
497497
StringWrapper_GetString = LibraryLoader.GetSymbolDelegate<StringWrapper_GetStringDelegate>(libraryHandle, "StringWrapper_GetString");
498498
Logging = LibraryLoader.GetSymbolDelegate<LoggingDelegate>(libraryHandle, "Logging");
499499
StopLogging = LibraryLoader.GetSymbolDelegate<StopLoggingDelegate>(libraryHandle, "StopLogging");
500+
501+
// editor only
502+
#if UNITY_EDITOR
503+
var symbol = LibraryLoader.GetSymbol(libraryHandle, "LLM_IsDebuggerAttached");
504+
LLM_IsDebuggerAttached = (symbol != IntPtr.Zero) ? Marshal.GetDelegateForFunctionPointer<LLM_IsDebuggerAttachedDelegate>(symbol) : null;
505+
#endif
500506
}
501507

502508
/// <summary>
@@ -606,6 +612,9 @@ public static string GetArchitecturePath(string arch)
606612
public delegate void StringWrapper_DeleteDelegate(IntPtr instance);
607613
public delegate int StringWrapper_GetStringSizeDelegate(IntPtr instance);
608614
public delegate void StringWrapper_GetStringDelegate(IntPtr instance, IntPtr buffer, int bufferSize, bool clear = false);
615+
#if UNITY_EDITOR
616+
public delegate bool LLM_IsDebuggerAttachedDelegate();
617+
#endif
609618

610619
public LoggingDelegate Logging;
611620
public StopLoggingDelegate StopLogging;
@@ -631,6 +640,9 @@ public static string GetArchitecturePath(string arch)
631640
public StringWrapper_DeleteDelegate StringWrapper_Delete;
632641
public StringWrapper_GetStringSizeDelegate StringWrapper_GetStringSize;
633642
public StringWrapper_GetStringDelegate StringWrapper_GetString;
643+
#if UNITY_EDITOR
644+
public LLM_IsDebuggerAttachedDelegate LLM_IsDebuggerAttached;
645+
#endif
634646

635647
#endif
636648

0 commit comments

Comments
 (0)