Leto.Framework
1.0.5
dotnet add package Leto.Framework --version 1.0.5
NuGet\Install-Package Leto.Framework -Version 1.0.5
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Leto.Framework" Version="1.0.5" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Leto.Framework" Version="1.0.5" />
<PackageReference Include="Leto.Framework" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Leto.Framework --version 1.0.5
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Leto.Framework, 1.0.5"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Leto.Framework@1.0.5
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Leto.Framework&version=1.0.5
#tool nuget:?package=Leto.Framework&version=1.0.5
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
# Leto Framework
Leto is a modular, flexible framework for building **voice and text-based banking assistants**. It provides a structured pipeline for **audio transcription, intent inference, entity extraction, session management**, and **intent handling**.
Clients can plug in **custom intent handlers, system prompts, and AI model configurations** while leveraging default implementations provided by the framework.
---
## Quick Start Minimal Example
This example shows a **working setup** with DI, a custom intent handler, and a system prompt provider.
### 1. Define a Custom Intent Handler and Guardrails
```csharp
public class CheckBalanceHandler : IntentHandlerBase
{
public override string BankingIntent => "CheckBalance";
protected override Dictionary<string, string?> DefaultSlots => new()
{
{ "AccountType", null },
{ "AccountNumber", null }
};
protected override async Task<IntentProcessingResponse> HandleIncompleteSlots(IntentProcessingRequest request)
{
var context = request.Session.CurrentIntentContext!;
var inferedAcctNumber = request.IntentInferenceResult?.IntentMetaData["AccountNumber"];
var inferedAcctType = request.IntentInferenceResult?.IntentMetaData["AccountType"];
// Fill slots from metadata if available
if (!string.IsNullOrWhiteSpace(inferedAcctNumber))
context.Slots["AccountNumber"] = inferedAcctNumber;
if (!string.IsNullOrWhiteSpace(inferedAcctType))
context.Slots["AccountType"] = inferedAcctType;
if (string.IsNullOrWhiteSpace(context.Slots["AccountType"]))
{
return new IntentProcessingResponse
{
DisplayResponse = "Do you want me to check your savings or current account?",
SpokenResponse = "Do you want me to check your savings or current account?",
IsComplete = false
};
}
if (string.IsNullOrWhiteSpace(context.Slots["AccountNumber"]))
{
return new IntentProcessingResponse
{
DisplayResponse = "Provide your account number?",
SpokenResponse = "Provide your account number?",
IsComplete = false
};
}
return await Task.FromResult(new IntentProcessingResponse
{
IsComplete = true,
DisplayResponse = MessageTemplates.AllSlotsFilledMessage,
SpokenResponse = MessageTemplates.AllSlotsFilledMessage
});
}
protected override Task<IntentProcessingResponse> ProcessRequest(IntentProcessingRequest request)
{
return Task.FromResult(new IntentProcessingResponse
{
DisplayResponse = "Your balance is NGN 500,000",
SpokenResponse = "Your balance is five hundred thousand naira",
IsComplete = true,
Timestamp = DateTime.UtcNow
});
}
}
public class CheckBalanceGuardrail : IIntentGuardrail
{
public string BankingIntent => "CheckBalance";
private readonly List<ISlotRule> _slotRules = new List<ISlotRule>
{
new SlotRule
{
SlotName = "AccountNumber",
IsRequired = true,
ValidateFunc = val => val is string s && s.Length == 10,
FixFunc = val => ""
},
new SlotRule
{
SlotName = "AccountType",
IsRequired = true,
ValidateFunc = val => val is string s && new[] { "savings", "current" }.Contains(s),
FixFunc = val => ""
}
};
List<ISlotRule> IIntentGuardrail.SlotRules => _slotRules;
}
2. Define a Custom System Prompt Provider
public class CheckBalancePromptProvider : ISystemPromptProvider
{
public string BankingIntent => "CheckBalance";
public string GetSystemPrompt()
{
return "You are a banking assistant. Extract required slots for checking account balance.";
}
}
3. Configure AI Model Settings
var aiSettings = new AIModelSettings
{
OpenAI = "https://api.openai.com/",
OpenAIKey = "your-api-key",
OpenAIDeploymentName = "your-deployment",
OpenAIApiVersion = "2023-03-15-preview"
};
var cacheSettings = new LetoCacheSettings
{
MessageCachePrefix = "ALAT_SAW_MSG",
SessionCachePrefix = "ALAT_SAW_SESSION",
CacheDurationInMinutes = 30
}
4. Register Leto Framework Services
public void ConfigureServices(IServiceCollection services)
{
// 1️ Register any services the client wants before the scan
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "REDIS_CONNECTION_STRING";
options.InstanceName = "LFT_"; // Optional prefix for keys
});
// 2️ Register Leto framework defaults (includes scanning and DI)
services.AddLetoFrameworkDefaults(
aiSettings,
cacheSettings,
options =>
{
options.UseGuardrails();
options.UseHandlerExecution();
});
}
5. Use LetoKernel to Handle Text or Audio
var response = await letoKernel.HandleTextAsync("Check my balance", cif);
Console.WriteLine(response.DisplayResponse);
Features
- Audio Transcription – Converts audio inputs to text (default: Azure Speech Transcriber).
- Intent Inference – Determines user intent using AI (default: OpenAI).
- Entity Extraction – Extracts slots/entities from user input (default: OpenAI).
- Session Management – Stores conversation history and context.
- Intent Handling – Execute business logic based on user intent.
- Dynamic Extensibility – Clients can provide custom intent handlers and system prompts.
Installation
Install via NuGet (replace <version> with latest):
dotnet add package Leto.Framework --version <version>
Configuration
Leto uses dependency injection for all components. The following services are required:
IAudioTranscriberIIntentIdentifierIIntentEntityExtractorISessionManagerIIntentMediatorIIntentOrchestratorIPromptProviderRegistry
Additionally, AI model settings can be configured via AIModelSettings.
Example appsettings.json
{
"AIModelSettings": {
"OpenAI": "https://api.openai.com/",
"OpenAIKey": "your-api-key",
"OpenAIDeploymentName": "your-deployment",
"OpenAIApiVersion": "2023-03-15-preview"
}
}
Extending Leto
Custom Intent Handlers
- Inherit from
IntentHandlerBase. - Implement
BankingIntentandHandleIntentmethods. - The handler will be auto-registered via
AddLetoFrameworkDefaults.
Custom System Prompts
Implement ISystemPromptProvider with Intent and GetSystemPrompt.
Custom AI Model Settings
Override defaults at runtime by passing a custom AIModelSettings instance to AddLetoFrameworkDefaults.
Session Management
Leto provides ISessionManager for:
- Storing conversation context
- Retrieving last N messages
- Clearing sessions
- Appending user/system messages
Contributing
- Fork the repository.
- Create a feature branch.
- Submit a pull request with tests.
- Ensure all existing tests pass.
License
MIT License. See LICENSE file for details.
Example Architecture
Audio/Text Input
|
v
LetoKernel
| \
| SessionManager
v
AudioTranscriber (if audio)
|
v
IntentIdentifier
|
v
IntentEntityExtractor
|
v
IntentMediator
|
v
Client-defined IntentHandlers
---
This gives clients:
- **Minimal example to get started quickly**
- **Clear DI registration instructions**
- **How to create custom handlers and prompts**
- **Architecture overview**
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.Extensions.Caching.StackExchangeRedis (>= 10.0.5)
- Newtonsoft.Json (>= 13.0.4)
- Scrutor (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.