Implement LLM provider configuration and update user settings

- Added functionality to update the default LLM provider for users via a new endpoint in UserController.
- Introduced LlmProvider enum to manage available LLM options: Auto, Gemini, OpenAI, and Claude.
- Updated User and UserEntity models to include DefaultLlmProvider property.
- Enhanced database context and migrations to support the new LLM provider configuration.
- Integrated LLM services into the application bootstrap for dependency injection.
- Updated TypeScript API client to include methods for managing LLM providers and chat requests.
This commit is contained in:
2026-01-03 21:55:55 +07:00
parent fb49190346
commit 6f55566db3
46 changed files with 7900 additions and 3 deletions

View File

@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Managing.Infrastructure.Databases.Migrations
{
/// <inheritdoc />
public partial class AddDefaultLlmProviderToUsers : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
// Add column with default value
migrationBuilder.AddColumn<string>(
name: "DefaultLlmProvider",
table: "Users",
type: "character varying(50)",
maxLength: 50,
nullable: true,
defaultValue: "auto");
// Update existing NULL values to default
migrationBuilder.Sql(@"
UPDATE ""Users""
SET ""DefaultLlmProvider"" = 'auto'
WHERE ""DefaultLlmProvider"" IS NULL;
");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DefaultLlmProvider",
table: "Users");
}
}
}

View File

@@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Managing.Infrastructure.Databases.Migrations
{
/// <inheritdoc />
public partial class ConvertDefaultLlmProviderToEnum : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
// Update existing "auto" values to "Auto" (enum format)
migrationBuilder.Sql(@"
UPDATE ""Users""
SET ""DefaultLlmProvider"" = 'Auto'
WHERE ""DefaultLlmProvider"" = 'auto' OR ""DefaultLlmProvider"" IS NULL;
");
// Alter column to use enum format (stored as text, default "Auto")
migrationBuilder.AlterColumn<string>(
name: "DefaultLlmProvider",
table: "Users",
type: "text",
nullable: true,
defaultValueSql: "'Auto'",
oldClrType: typeof(string),
oldType: "character varying(50)",
oldMaxLength: 50,
oldNullable: true,
oldDefaultValue: "auto");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
// Revert "Auto" values back to "auto" (lowercase)
migrationBuilder.Sql(@"
UPDATE ""Users""
SET ""DefaultLlmProvider"" = 'auto'
WHERE ""DefaultLlmProvider"" = 'Auto';
");
migrationBuilder.AlterColumn<string>(
name: "DefaultLlmProvider",
table: "Users",
type: "character varying(50)",
maxLength: 50,
nullable: true,
defaultValue: "auto",
oldClrType: typeof(string),
oldType: "text",
oldNullable: true,
oldDefaultValueSql: "'Auto'");
}
}
}

View File

@@ -1441,6 +1441,11 @@ namespace Managing.Infrastructure.Databases.Migrations
b.Property<string>("DefaultExchange")
.HasColumnType("text");
b.Property<string>("DefaultLlmProvider")
.ValueGeneratedOnAdd()
.HasColumnType("text")
.HasDefaultValueSql("'Auto'");
b.Property<bool>("EnableAutoswap")
.HasColumnType("boolean");

View File

@@ -34,6 +34,9 @@ public class UserEntity
[Column(TypeName = "decimal(5,4)")] public decimal? SignalAgreementThreshold { get; set; } = 0.5m; // Default: 50% agreement required
public bool? AllowSignalTrendOverride { get; set; } = true; // Default: Allow signal strategies to override trends
public TradingExchanges? DefaultExchange { get; set; } = TradingExchanges.GmxV2; // Default exchange
// User Settings - LLM Configuration
public LlmProvider? DefaultLlmProvider { get; set; } = LlmProvider.Auto; // Default LLM provider
// Navigation properties
public virtual ICollection<AccountEntity> Accounts { get; set; } = new List<AccountEntity>();

View File

@@ -105,6 +105,9 @@ public class ManagingDbContext : DbContext
.HasConversion<string>(); // Store enum as string
entity.Property(e => e.DefaultExchange)
.HasConversion<string>(); // Store enum as string
entity.Property(e => e.DefaultLlmProvider)
.HasConversion<string>() // Store enum as string
.HasDefaultValueSql("'Auto'"); // Default LLM provider
// Create indexes for performance
entity.HasIndex(e => e.Name).IsUnique();

View File

@@ -146,6 +146,7 @@ public static class PostgreSqlMappers
SignalAgreementThreshold = entity.SignalAgreementThreshold,
AllowSignalTrendOverride = entity.AllowSignalTrendOverride,
DefaultExchange = entity.DefaultExchange,
DefaultLlmProvider = entity.DefaultLlmProvider,
Accounts = entity.Accounts?.Select(MapAccountWithoutUser).ToList() ?? new List<Account>()
};
}
@@ -193,7 +194,8 @@ public static class PostgreSqlMappers
TrendStrongAgreementThreshold = user.TrendStrongAgreementThreshold,
SignalAgreementThreshold = user.SignalAgreementThreshold,
AllowSignalTrendOverride = user.AllowSignalTrendOverride,
DefaultExchange = user.DefaultExchange
DefaultExchange = user.DefaultExchange,
DefaultLlmProvider = user.DefaultLlmProvider
};
}

View File

@@ -269,6 +269,7 @@ public class PostgreSqlUserRepository : BaseRepositoryWithLogging, IUserReposito
existingUser.SignalAgreementThreshold = user.SignalAgreementThreshold;
existingUser.AllowSignalTrendOverride = user.AllowSignalTrendOverride;
existingUser.DefaultExchange = user.DefaultExchange;
existingUser.DefaultLlmProvider = user.DefaultLlmProvider;
_context.Users.Update(existingUser);