V2 / df3fc286644d
Core.cs
Lilith/Core/Core.cs
Unchanged from the preceding versionCS
namespace Lilith.Core;
/// <summary>
/// Root hub for agent addons. Create one instance and access <see cref="Logger"/>,
/// <see cref="OllamaClient"/>, and future services from the same object.
/// </summary>
public class Core(Action<LogEntry>? onLog = null) : IDisposable
{
private static readonly Lazy<Core> Shared = new(() => new());
private readonly object _sync = new();
private OllamaClient? _client;
private bool _ownsClient;
private bool _disposed;
/// <summary>Shared application core (optional).</summary>
public static Core Default => Shared.Value;
/// <summary>Subscribe-based logging (console, GUI, file, etc.).</summary>
public Logger Logger { get; } = new(onLog);
/// <summary>
/// Ollama client addon. Assign after construction or via <see cref="UseOllamaAsync"/>.
/// </summary>
public OllamaClient? OllamaClient
{
get { lock (_sync) { ObjectDisposedException.ThrowIf(_disposed, this); return _client; } }
set => Attach(value, owned: false);
}
/// <summary>Attach an Ollama client and return it for chaining.</summary>
public OllamaClient UseOllama(OllamaClient ollamaClient)
{
Attach(ollamaClient ?? throw new ArgumentNullException(nameof(ollamaClient)), owned: false);
return ollamaClient;
}
/// <summary>
/// Creates and attaches a client for an already prepared model. Installation/download
/// are explicit setup operations; this method only starts/checks the server and validates readiness.
/// </summary>
public async Task<OllamaClient> UseOllamaAsync(string model, string systemPrompt, bool startOllamaIfNotRunning = true)
{
lock (_sync) ObjectDisposedException.ThrowIf(_disposed, this);
var client = await OllamaClient.CreateClient(model, systemPrompt, Logger, startOllamaIfNotRunning);
try { Attach(client, owned: true); return client; }
catch { client.Dispose(); throw; }
}
/// <summary>External attachments are borrowed; clients created by UseOllamaAsync are owned.</summary>
internal void Attach(OllamaClient? client, bool owned)
{
lock (_sync)
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (ReferenceEquals(_client, client)) return;
if (_ownsClient) _client?.Dispose();
_client = client;
_ownsClient = owned;
}
}
public void Dispose()
{
lock (_sync)
{
if (_disposed) return;
if (_ownsClient) _client?.Dispose();
_disposed = true;
_client = null;
_ownsClient = false;
}
GC.SuppressFinalize(this);
}
}