-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Code(API::CreateAssistant): Implement create assistant feature
- Loading branch information
1 parent
8820eca
commit 411cbcc
Showing
3 changed files
with
103 additions
and
0 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
src/Server/StellarChat.Server.Api/Features/Assistants/CreateAssistant/CreateAssistant.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace StellarChat.Server.Api.Features.Assistants.CreateAssistant; | ||
|
||
internal sealed record CreateAssistant( | ||
[Required] Guid Id, | ||
string Name, | ||
string Metaprompt, | ||
string Description, | ||
string AvatarUrl, | ||
string DefaultModel, | ||
string DefaultVoice, | ||
bool IsDefault) : ICommand; |
32 changes: 32 additions & 0 deletions
32
...ver/StellarChat.Server.Api/Features/Assistants/CreateAssistant/CreateAssistantEndpoint.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using StellarChat.Server.Api.Features.Chat.CreateChatSession; | ||
|
||
namespace StellarChat.Server.Api.Features.Assistants.CreateAssistant; | ||
|
||
internal sealed class CreateAssistantEndpoint : IEndpoint | ||
{ | ||
public void Expose(IEndpointRouteBuilder endpoints) | ||
{ | ||
var assistants = endpoints.MapGroup("/assistants").WithTags("Assistants"); | ||
|
||
assistants.MapPost("", async ([FromBody] CreateAssistantRequest request, IMediator mediator) => | ||
{ | ||
var id = Guid.NewGuid(); | ||
var command = request.Adapt<CreateAssistant>(); | ||
|
||
command = command with { Id = id }; | ||
await mediator.Send(command); | ||
|
||
return Results.CreatedAtRoute("GetAssistant", new { Id = id }, id); | ||
}) | ||
.Produces(StatusCodes.Status201Created) | ||
.Produces(StatusCodes.Status400BadRequest) | ||
.WithOpenApi(operation => new(operation) | ||
{ | ||
Summary = "Creates a new assistant." | ||
}); | ||
} | ||
|
||
public void Register(IServiceCollection services, IConfiguration configuration) { } | ||
|
||
public void Use(IApplicationBuilder app) { } | ||
} |
60 changes: 60 additions & 0 deletions
60
...rver/StellarChat.Server.Api/Features/Assistants/CreateAssistant/CreateAssistantHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
namespace StellarChat.Server.Api.Features.Assistants.CreateAssistant; | ||
|
||
internal sealed class CreateAssistantHandler : ICommandHandler<CreateAssistant> | ||
{ | ||
private readonly IAssistantRepository _assistantRepository; | ||
private readonly TimeProvider _clock; | ||
private readonly ILogger<CreateAssistantHandler> _logger; | ||
|
||
public CreateAssistantHandler(IAssistantRepository assistantRepository, TimeProvider clock, ILogger<CreateAssistantHandler> logger) | ||
{ | ||
_assistantRepository = assistantRepository; | ||
_clock = clock; | ||
_logger = logger; | ||
} | ||
|
||
public async ValueTask<Unit> Handle(CreateAssistant command, CancellationToken cancellationToken) | ||
{ | ||
if (await _assistantRepository.ExistsAsync(command.Id)) | ||
{ | ||
throw new AssistantAlreadyExistsException(command.Id); | ||
} | ||
|
||
var now = _clock.GetUtcNow(); | ||
|
||
if (command.IsDefault) | ||
{ | ||
await UnsetPreviousDefaultAssistant(); | ||
} | ||
|
||
var assistant = Assistant.Create( | ||
command.Id, | ||
command.Name, | ||
command.Metaprompt, | ||
command.Description, | ||
command.AvatarUrl, | ||
command.DefaultModel, | ||
command.DefaultVoice, | ||
command.IsDefault, | ||
createdAt: now, | ||
updatedAt: now); | ||
|
||
await _assistantRepository.AddAsync(assistant); | ||
_logger.LogInformation($"Assistant with ID: '{assistant.Id}' has been created."); | ||
|
||
return Unit.Value; | ||
} | ||
|
||
private async Task UnsetPreviousDefaultAssistant() | ||
{ | ||
var assistants = await _assistantRepository.BrowseAsync(); | ||
var currentDefaultAssistant = assistants.SingleOrDefault(assistant => assistant.IsDefault); | ||
|
||
if (currentDefaultAssistant is not null) | ||
{ | ||
currentDefaultAssistant.IsDefault = false; | ||
await _assistantRepository.UpdateAsync(currentDefaultAssistant); | ||
} | ||
} | ||
} | ||
|