diff --git a/src/dotnet/Common/Models/Chat/ChatSessionProperties.cs b/src/dotnet/Common/Models/Chat/ChatSessionProperties.cs new file mode 100644 index 0000000000..97e1384bf0 --- /dev/null +++ b/src/dotnet/Common/Models/Chat/ChatSessionProperties.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace FoundationaLLM.Common.Models.Chat +{ + /// + /// The session properties object. + /// + public class ChatSessionProperties + { + /// + /// The session name. + /// + [JsonPropertyName("name")] + public required string Name { get; set; } + } +} diff --git a/src/dotnet/Core/Interfaces/ICoreService.cs b/src/dotnet/Core/Interfaces/ICoreService.cs index 27cc886576..1915ae7b0f 100644 --- a/src/dotnet/Core/Interfaces/ICoreService.cs +++ b/src/dotnet/Core/Interfaces/ICoreService.cs @@ -26,15 +26,16 @@ public interface ICoreService /// Creates a new chat session. /// /// The instance Id. - Task CreateNewChatSessionAsync(string instanceId); + /// The session properties. + Task CreateNewChatSessionAsync(string instanceId, ChatSessionProperties chatSessionProperties); /// /// Rename the chat session from its default (eg., "New Chat") to the summary provided by OpenAI. /// /// The instance id. /// The session id to rename. - /// The new name for the chat session. - Task RenameChatSessionAsync(string instanceId, string sessionId, string newChatSessionName); + /// The session properties. + Task RenameChatSessionAsync(string instanceId, string sessionId, ChatSessionProperties chatSessionProperties); /// /// Delete a chat session and related messages. @@ -58,14 +59,6 @@ public interface ICoreService /// The completion request. Task GetCompletionAsync(string instanceId, CompletionRequest directCompletionRequest); - /// - /// Generate a name for a chat message, based on the passed in prompt. - /// - /// The instance id. - /// The session id to rename. - /// The text to use when generating the name. - Task GenerateChatSessionNameAsync(string instanceId, string? sessionId, string? text); - /// /// Rate an assistant message. This can be used to discover useful AI responses for training, discoverability, and other benefits down the road. /// diff --git a/src/dotnet/Core/Interfaces/ICosmosDbService.cs b/src/dotnet/Core/Interfaces/ICosmosDbService.cs index fb0ce9f8b7..5f4bc81674 100644 --- a/src/dotnet/Core/Interfaces/ICosmosDbService.cs +++ b/src/dotnet/Core/Interfaces/ICosmosDbService.cs @@ -80,10 +80,10 @@ public interface ICosmosDbService /// Updates a session's name through a patch operation. /// /// The session id. - /// The session's new name. + /// The session's new name. /// Cancellation token for async calls. /// Revised chat session item. - Task UpdateSessionNameAsync(string id, string name, CancellationToken cancellationToken = default); + Task UpdateSessionNameAsync(string id, string sessionName, CancellationToken cancellationToken = default); /// /// Batch create or update chat messages and session. diff --git a/src/dotnet/Core/Services/CoreService.cs b/src/dotnet/Core/Services/CoreService.cs index 3afaf80a69..c14b2e4bce 100644 --- a/src/dotnet/Core/Services/CoreService.cs +++ b/src/dotnet/Core/Services/CoreService.cs @@ -1,4 +1,3 @@ -using Azure.Core; using FoundationaLLM.Common.Constants; using FoundationaLLM.Common.Constants.ResourceProviders; using FoundationaLLM.Common.Exceptions; @@ -66,10 +65,13 @@ public async Task> GetChatSessionMessagesAsync(string instanceId, } /// - public async Task CreateNewChatSessionAsync(string instanceId) + public async Task CreateNewChatSessionAsync(string instanceId, ChatSessionProperties chatSessionProperties) { + ArgumentException.ThrowIfNullOrEmpty(chatSessionProperties.Name); + Session session = new() { + Name = chatSessionProperties.Name, Type = _sessionType, UPN = _callContext.CurrentUserIdentity?.UPN ?? throw new InvalidOperationException("Failed to retrieve the identity of the signed in user when creating a new chat session.") }; @@ -77,12 +79,12 @@ public async Task CreateNewChatSessionAsync(string instanceId) } /// - public async Task RenameChatSessionAsync(string instanceId, string sessionId, string newChatSessionName) + public async Task RenameChatSessionAsync(string instanceId, string sessionId, ChatSessionProperties chatSessionProperties) { ArgumentNullException.ThrowIfNull(sessionId); - ArgumentException.ThrowIfNullOrEmpty(newChatSessionName); + ArgumentException.ThrowIfNullOrEmpty(chatSessionProperties.Name); - return await _cosmosDbService.UpdateSessionNameAsync(sessionId, newChatSessionName); + return await _cosmosDbService.UpdateSessionNameAsync(sessionId, chatSessionProperties.Name); } /// @@ -179,26 +181,6 @@ public Task GetCompletionOperationStatus(string instanceId public async Task GetCompletionOperationResult(string instanceId, string operationId) => throw new NotImplementedException(); - /// - public async Task GenerateChatSessionNameAsync(string instanceId, string? sessionId, string? text) - { - try - { - ArgumentNullException.ThrowIfNull(sessionId); - - var sessionName = string.Empty; - sessionName = $"{DateTime.UtcNow:yyyy-MM-dd HH:mm}"; - await RenameChatSessionAsync(instanceId, sessionId, sessionName); - - return new Completion { Text = sessionName }; - } - catch (Exception ex) - { - _logger.LogError(ex, $"Error generating session name for session {sessionId} for text [{text}]."); - return new Completion { Text = "[No Name]" }; - } - } - private IDownstreamAPIService GetDownstreamAPIService(AgentGatekeeperOverrideOption agentOption) => ((agentOption == AgentGatekeeperOverrideOption.UseSystemOption) && _settings.BypassGatekeeper) || (agentOption == AgentGatekeeperOverrideOption.MustBypass) diff --git a/src/dotnet/Core/Services/CosmosDbService.cs b/src/dotnet/Core/Services/CosmosDbService.cs index 9f42477849..7d9fce832c 100644 --- a/src/dotnet/Core/Services/CosmosDbService.cs +++ b/src/dotnet/Core/Services/CosmosDbService.cs @@ -223,14 +223,14 @@ public async Task UpdateSessionAsync(Session session, CancellationToken } /// - public async Task UpdateSessionNameAsync(string id, string name, CancellationToken cancellationToken = default) + public async Task UpdateSessionNameAsync(string id, string sessionName, CancellationToken cancellationToken = default) { var response = await _sessions.PatchItemAsync( id: id, partitionKey: new PartitionKey(id), patchOperations: new[] { - PatchOperation.Set("/name", name), + PatchOperation.Set("/name", sessionName), }, cancellationToken: cancellationToken ); diff --git a/src/dotnet/CoreAPI/Controllers/SessionsController.cs b/src/dotnet/CoreAPI/Controllers/SessionsController.cs index b7a484a469..2bb45ecb18 100644 --- a/src/dotnet/CoreAPI/Controllers/SessionsController.cs +++ b/src/dotnet/CoreAPI/Controllers/SessionsController.cs @@ -68,19 +68,20 @@ public async Task GetCompletionPrompt(string instanceId, strin /// Creates a new chat session. /// /// The id of the instance. + /// The session properties. [HttpPost(Name = "CreateNewChatSession")] - public async Task CreateNewChatSession(string instanceId) => - await _coreService.CreateNewChatSessionAsync(instanceId); + public async Task CreateNewChatSession(string instanceId, [FromBody] ChatSessionProperties chatSessionProperties) => + await _coreService.CreateNewChatSessionAsync(instanceId, chatSessionProperties); /// /// Rename the chat session. /// /// The id of the instance. /// The id of the session to rename. - /// The new name for the session. + /// The session properties. [HttpPost("{sessionId}/rename", Name = "RenameChatSession")] - public async Task RenameChatSession(string instanceId, string sessionId, string newChatSessionName) => - await _coreService.RenameChatSessionAsync(instanceId, sessionId, newChatSessionName); + public async Task RenameChatSession(string instanceId, string sessionId, [FromBody] ChatSessionProperties chatSessionProperties) => + await _coreService.RenameChatSessionAsync(instanceId, sessionId, chatSessionProperties); /// /// Delete a chat session and related messages. @@ -90,15 +91,5 @@ public async Task RenameChatSession(string instanceId, string sessionId [HttpDelete("{sessionId}", Name = "DeleteChatSession")] public async Task DeleteChatSession(string instanceId, string sessionId) => await _coreService.DeleteChatSessionAsync(instanceId, sessionId); - - /// - /// Generate a name for a chat message, based on the passed in prompt. - /// - /// The id of the instance. - /// The id of the session for which to generate a name. - /// The prompt to use to generate the name. - [HttpPost("{sessionId}/generate-name", Name = "GenerateChatSessionName")] - public async Task GenerateChatSessionName(string instanceId, string sessionId, [FromBody] string text) => - await _coreService.GenerateChatSessionNameAsync(instanceId, sessionId, text); } } diff --git a/src/dotnet/CoreClient/Clients/RESTClients/SessionRESTClient.cs b/src/dotnet/CoreClient/Clients/RESTClients/SessionRESTClient.cs index 9f0ad22abb..4ea6a3841e 100644 --- a/src/dotnet/CoreClient/Clients/RESTClients/SessionRESTClient.cs +++ b/src/dotnet/CoreClient/Clients/RESTClients/SessionRESTClient.cs @@ -1,8 +1,8 @@ -using System.Text.Encodings.Web; -using System.Text.Json; -using Azure.Core; +using Azure.Core; using FoundationaLLM.Client.Core.Interfaces; using FoundationaLLM.Common.Models.Chat; +using System.Net.Http.Json; +using System.Text.Json; namespace FoundationaLLM.Client.Core.Clients.RESTClients { @@ -17,10 +17,12 @@ internal class SessionRESTClient( private readonly string _instanceId = instanceId ?? throw new ArgumentNullException(nameof(instanceId)); /// - public async Task CreateSessionAsync() + public async Task CreateSessionAsync(ChatSessionProperties chatSessionProperties) { var coreClient = await GetCoreClientAsync(); - var responseSession = await coreClient.PostAsync($"instances/{_instanceId}/sessions", null); + var responseSession = await coreClient.PostAsync( + $"instances/{_instanceId}/sessions", + JsonContent.Create(chatSessionProperties)); if (responseSession.IsSuccessStatusCode) { @@ -36,14 +38,16 @@ public async Task CreateSessionAsync() } /// - public async Task RenameChatSession(string sessionId, string sessionName) + public async Task RenameChatSession(string sessionId, ChatSessionProperties chatSessionProperties) { var coreClient = await GetCoreClientAsync(); - var response = await coreClient.PostAsync($"instances/{_instanceId}/sessions/{sessionId}/rename?newChatSessionName={UrlEncoder.Default.Encode(sessionName)}", null); + var response = await coreClient.PostAsync( + $"instances/{_instanceId}/sessions/{sessionId}/rename", + JsonContent.Create(chatSessionProperties)); if (response.IsSuccessStatusCode) { - return sessionName; + return chatSessionProperties.Name; } throw new Exception($"Failed to rename chat session. Status code: {response.StatusCode}. Reason: {response.ReasonPhrase}"); diff --git a/src/dotnet/CoreClient/CoreClient.cs b/src/dotnet/CoreClient/CoreClient.cs index 24f065d709..af77270477 100644 --- a/src/dotnet/CoreClient/CoreClient.cs +++ b/src/dotnet/CoreClient/CoreClient.cs @@ -54,24 +54,29 @@ public CoreClient( _coreRestClient = new CoreRESTClient(coreUri, credential, instanceId, options); /// - public async Task CreateChatSessionAsync(string? sessionName) + public async Task CreateChatSessionAsync(ChatSessionProperties chatSessionProperties) { - var sessionId = await _coreRestClient.Sessions.CreateSessionAsync(); - if (!string.IsNullOrWhiteSpace(sessionName)) - { - await _coreRestClient.Sessions.RenameChatSession(sessionId, sessionName); - } + if (string.IsNullOrWhiteSpace(chatSessionProperties.Name)) + throw new ArgumentException("A session name must be provided when creating a new session."); + var sessionId = await _coreRestClient.Sessions.CreateSessionAsync(chatSessionProperties); return sessionId; } /// - public async Task GetCompletionWithSessionAsync(string? sessionId, string? sessionName, + public async Task GetCompletionWithSessionAsync(string? sessionId, ChatSessionProperties? chatSessionProperties, string userPrompt, string agentName) { if (string.IsNullOrWhiteSpace(sessionId)) { - sessionId = await CreateChatSessionAsync(sessionName); + if (chatSessionProperties == null) + { + throw new ArgumentException( + "The completion request must contain a session name if no session Id is provided. " + + "A new session will be created with the provided session name."); + } + + sessionId = await CreateChatSessionAsync(chatSessionProperties); } var orchestrationRequest = new CompletionRequest @@ -81,6 +86,7 @@ public async Task GetCompletionWithSessionAsync(string? sessionId, s SessionId = sessionId, UserPrompt = userPrompt }; + return await GetCompletionWithSessionAsync(orchestrationRequest); } @@ -126,7 +132,7 @@ public async Task GetCompletionAsync(CompletionRequest completionReq /// public async Task AttachFileAndAskQuestionAsync(Stream fileStream, string fileName, string contentType, - string agentName, string question, bool useSession, string? sessionId, string? sessionName) + string agentName, string question, bool useSession, string? sessionId, ChatSessionProperties? chatSessionProperties) { if (fileStream == null) { @@ -139,7 +145,14 @@ public async Task AttachFileAndAskQuestionAsync(Stream fileStream, s { if (string.IsNullOrWhiteSpace(sessionId)) { - sessionId = await CreateChatSessionAsync(sessionName); + if (chatSessionProperties == null) + { + throw new ArgumentException( + "The completion request must contain a session name if no session Id is provided. " + + "A new session will be created with the provided session name."); + } + + sessionId = await CreateChatSessionAsync(chatSessionProperties); } var orchestrationRequest = new CompletionRequest diff --git a/src/dotnet/CoreClient/Interfaces/ICoreClient.cs b/src/dotnet/CoreClient/Interfaces/ICoreClient.cs index 8971942853..d3d5a23401 100644 --- a/src/dotnet/CoreClient/Interfaces/ICoreClient.cs +++ b/src/dotnet/CoreClient/Interfaces/ICoreClient.cs @@ -12,11 +12,11 @@ namespace FoundationaLLM.Client.Core.Interfaces public interface ICoreClient { /// - /// Creates a new chat session and renames it if a session name is provided. + /// Creates a new chat session with the specified name. /// - /// Renames the new chat session if not null or empty. + /// The session properties. /// The new chat session ID. - Task CreateChatSessionAsync(string? sessionName); + Task CreateChatSessionAsync(ChatSessionProperties sessionProperties); /// /// Runs a single completion request with an agent using the Core API and a chat session. @@ -25,12 +25,12 @@ public interface ICoreClient /// /// The ID of an existing session. If null or empty, a new session /// is created first. - /// Renames the new chat session if not null or empty. + /// Optional session priperties. /// The user prompt to send to the agent. /// The name of the FoundationaLLM agent that will handle the /// completion request. /// A completion from the designated FoundationaLLM agent. - Task GetCompletionWithSessionAsync(string? sessionId, string? sessionName, + Task GetCompletionWithSessionAsync(string? sessionId, ChatSessionProperties? sessionProperties, string userPrompt, string agentName); /// @@ -83,11 +83,11 @@ Task GetCompletionWithSessionAsync(string? sessionId, string? sessio /// false, no session is created and the sessionless orchestration flow is used. /// The ID of an existing session. If null or empty, a new session /// is created first. - /// Renames the new chat session if not null or empty. + /// Optional session properties. /// A completion from the designated FoundationaLLM agent. /// A completion from the designated FoundationaLLM agent. Task AttachFileAndAskQuestionAsync(Stream fileStream, string fileName, string contentType, - string agentName, string question, bool useSession, string? sessionId, string? sessionName); + string agentName, string question, bool useSession, string? sessionId, ChatSessionProperties? chatSessionProperties); /// /// Returns the chat messages related to an existing session. diff --git a/src/dotnet/CoreClient/Interfaces/ISessionRESTClient.cs b/src/dotnet/CoreClient/Interfaces/ISessionRESTClient.cs index 04264fd4de..7b20dcd538 100644 --- a/src/dotnet/CoreClient/Interfaces/ISessionRESTClient.cs +++ b/src/dotnet/CoreClient/Interfaces/ISessionRESTClient.cs @@ -1,5 +1,4 @@ using FoundationaLLM.Common.Models.Chat; -using FoundationaLLM.Common.Models.Orchestration; namespace FoundationaLLM.Client.Core.Interfaces { @@ -24,18 +23,19 @@ public interface ISessionRESTClient Task RateMessageAsync(string sessionId, string messageId, bool rating); /// - /// Creates and renames a session. + /// Creates a new session with the specified name. /// + /// The session properties. /// Returns the new Session ID. - Task CreateSessionAsync(); + Task CreateSessionAsync(ChatSessionProperties chatSessionProperties); /// /// Renames a chat session. /// /// The chat session ID. - /// The new session name. + /// The session properties. /// - Task RenameChatSession(string sessionId, string sessionName); + Task RenameChatSession(string sessionId, ChatSessionProperties chatSessionProperties); /// /// Gets a completion prompt by session ID and completion prompt ID. diff --git a/tests/dotnet/Core.Client.Tests/CoreClientTests.cs b/tests/dotnet/Core.Client.Tests/CoreClientTests.cs index 84e6c883a7..60233562f0 100644 --- a/tests/dotnet/Core.Client.Tests/CoreClientTests.cs +++ b/tests/dotnet/Core.Client.Tests/CoreClientTests.cs @@ -24,17 +24,16 @@ public CoreClientTests() public async Task CreateChatSessionAsync_WithName_CreatesAndRenamesSession() { // Arrange - var sessionName = "TestSession"; + var chatSessionProperties = new ChatSessionProperties() { Name = "TestSession" }; var sessionId = "session-id"; - _coreRestClient.Sessions.CreateSessionAsync().Returns(Task.FromResult(sessionId)); + _coreRestClient.Sessions.CreateSessionAsync(chatSessionProperties).Returns(Task.FromResult(sessionId)); // Act - var result = await _coreClient.CreateChatSessionAsync(sessionName); + var result = await _coreClient.CreateChatSessionAsync(chatSessionProperties); // Assert Assert.Equal(sessionId, result); - await _coreRestClient.Sessions.Received(1).CreateSessionAsync(); - await _coreRestClient.Sessions.Received(1).RenameChatSession(sessionId, sessionName); + await _coreRestClient.Sessions.Received(1).CreateSessionAsync(chatSessionProperties); } [Fact] @@ -43,17 +42,18 @@ public async Task GetCompletionWithSessionAsync_WithNewSession_CreatesSessionAnd // Arrange var userPrompt = "Hello, World!"; var agentName = "TestAgent"; + var chatSessionProperties = new ChatSessionProperties() { Name = "TestSession" }; var sessionId = "new-session-id"; var completion = new Completion(); - _coreRestClient.Sessions.CreateSessionAsync().Returns(Task.FromResult(sessionId)); + _coreRestClient.Sessions.CreateSessionAsync(chatSessionProperties).Returns(Task.FromResult(sessionId)); _coreRestClient.Completions.GetChatCompletionAsync(Arg.Any()).Returns(Task.FromResult(completion)); // Act - var result = await _coreClient.GetCompletionWithSessionAsync(null, "NewSession", userPrompt, agentName); + var result = await _coreClient.GetCompletionWithSessionAsync(null, chatSessionProperties, userPrompt, agentName); // Assert Assert.Equal(completion, result); - await _coreRestClient.Sessions.Received(1).CreateSessionAsync(); + await _coreRestClient.Sessions.Received(1).CreateSessionAsync(chatSessionProperties); await _coreRestClient.Completions.GetChatCompletionAsync(Arg.Is( r => r.SessionId == sessionId && r.AgentName == agentName && r.UserPrompt == userPrompt)); } @@ -100,20 +100,21 @@ public async Task AttachFileAndAskQuestionAsync_UsesSession_UploadsFileAndSendsS var contentType = "text/plain"; var agentName = "TestAgent"; var question = "What is this file about?"; + var chatSessionProperties = new ChatSessionProperties() { Name = "TestSession" }; var sessionId = "session-id"; var objectId = "object-id"; var completion = new Completion(); _coreRestClient.Attachments.UploadAttachmentAsync(fileStream, fileName, contentType).Returns(Task.FromResult(objectId)); - _coreRestClient.Sessions.CreateSessionAsync().Returns(Task.FromResult(sessionId)); + _coreRestClient.Sessions.CreateSessionAsync(chatSessionProperties).Returns(Task.FromResult(sessionId)); _coreRestClient.Completions.GetChatCompletionAsync(Arg.Any()).Returns(Task.FromResult(completion)); // Act - var result = await _coreClient.AttachFileAndAskQuestionAsync(fileStream, fileName, contentType, agentName, question, true, null, "NewSession"); + var result = await _coreClient.AttachFileAndAskQuestionAsync(fileStream, fileName, contentType, agentName, question, true, null, chatSessionProperties); // Assert Assert.Equal(completion, result); await _coreRestClient.Attachments.Received(1).UploadAttachmentAsync(fileStream, fileName, contentType); - await _coreRestClient.Sessions.Received(1).CreateSessionAsync(); + await _coreRestClient.Sessions.Received(1).CreateSessionAsync(chatSessionProperties); await _coreRestClient.Completions.GetChatCompletionAsync(Arg.Is( r => r.AgentName == agentName && r.SessionId == sessionId && r.UserPrompt == question && r.Attachments.Contains(objectId))); } @@ -123,7 +124,9 @@ public async Task AttachFileAndAskQuestionAsync_ThrowsException_WhenFileStreamIs { // Arrange & Act & Assert await Assert.ThrowsAsync(() => - _coreClient.AttachFileAndAskQuestionAsync(null!, "file.txt", "text/plain", "agent", "question", true, "session-id", "session-name")); + _coreClient.AttachFileAndAskQuestionAsync( + null!, "file.txt", "text/plain", "agent", "question", true, "session-id", + new ChatSessionProperties() { Name = "session-name" })); } [Fact] diff --git a/tests/dotnet/Core.Examples/Services/AgentConversationTestService.cs b/tests/dotnet/Core.Examples/Services/AgentConversationTestService.cs index b88fa10ea4..0c10326d71 100644 --- a/tests/dotnet/Core.Examples/Services/AgentConversationTestService.cs +++ b/tests/dotnet/Core.Examples/Services/AgentConversationTestService.cs @@ -36,7 +36,7 @@ public async Task> RunAgentConversationWithSession( if (string.IsNullOrWhiteSpace(sessionId)) { // Create a new session since an existing ID was not provided. - sessionId = await coreClient.CreateChatSessionAsync((string?) null); + sessionId = await coreClient.CreateChatSessionAsync(new ChatSessionProperties() { Name = "Test" }); sessionCreated = true; } @@ -74,7 +74,7 @@ public async Task RunAgentCompletionWithSession(string agentName, if (string.IsNullOrWhiteSpace(sessionId)) { // Create a new session since an existing ID was not provided. - sessionId = await coreClient.CreateChatSessionAsync((string?) null); + sessionId = await coreClient.CreateChatSessionAsync(new ChatSessionProperties() { Name = "Test" }); sessionCreated = true; } @@ -148,7 +148,7 @@ public async Task RunAgentCompletionWithQual if (string.IsNullOrWhiteSpace(sessionId)) { // Create a new session since an existing ID was not provided. - sessionId = await coreClient.CreateChatSessionAsync((string?) null); + sessionId = await coreClient.CreateChatSessionAsync(new ChatSessionProperties() { Name = "Test" }); sessionCreated = true; } diff --git a/tests/dotnet/Core.Tests/Services/CoreServiceTests.cs b/tests/dotnet/Core.Tests/Services/CoreServiceTests.cs index b9332dab8e..5d2a242e0d 100644 --- a/tests/dotnet/Core.Tests/Services/CoreServiceTests.cs +++ b/tests/dotnet/Core.Tests/Services/CoreServiceTests.cs @@ -123,7 +123,8 @@ public async Task CreateNewChatSessionAsync_ShouldReturnANewChatSession() // Arrange var currentUserUPN = "testuser@example.com"; var sessionType = "Test_type"; - var newSession = new Session { Type = sessionType, UPN = currentUserUPN }; + var chatSessionProperties = new ChatSessionProperties() { Name = "Test_name" }; + var newSession = new Session { Name = chatSessionProperties.Name, Type = sessionType, UPN = currentUserUPN }; // Set up mock returns _callContext.CurrentUserIdentity.Returns(new UnifiedUserIdentity { UPN = currentUserUPN }); @@ -132,12 +133,13 @@ public async Task CreateNewChatSessionAsync_ShouldReturnANewChatSession() .Returns(Task.FromResult(newSession)); // Act - var resultSession = await _testedService.CreateNewChatSessionAsync(_instanceId); + var resultSession = await _testedService.CreateNewChatSessionAsync(_instanceId, chatSessionProperties); // Assert Assert.NotNull(resultSession); Assert.Equal(sessionType, resultSession.Type); Assert.Equal(currentUserUPN, resultSession.UPN); + Assert.Equal(chatSessionProperties.Name, resultSession.Name); } #endregion @@ -149,37 +151,37 @@ public async Task RenameChatSessionAsync_ShouldReturnTheRenamedChatSession() { // Arrange var session = new Session() { Name = "OldName" }; - var expectedName = "NewName"; + var chatSessionProperties = new ChatSessionProperties() { Name = "NewName" }; var expectedSession = new Session() { Id = session.Id, Messages = session.Messages, - Name = expectedName, + Name = chatSessionProperties.Name, SessionId = session.SessionId, TokensUsed = session.TokensUsed, Type = session.Type, }; - _cosmosDbService.UpdateSessionNameAsync(session.Id, expectedName).Returns(expectedSession); + _cosmosDbService.UpdateSessionNameAsync(session.Id, chatSessionProperties.Name).Returns(expectedSession); // Act - var actualSession = await _testedService.RenameChatSessionAsync(_instanceId, session.Id, expectedName); + var actualSession = await _testedService.RenameChatSessionAsync(_instanceId, session.Id, chatSessionProperties); // Assert Assert.Equivalent(expectedSession, actualSession); - Assert.Equal(expectedName, actualSession.Name); + Assert.Equal(chatSessionProperties.Name, actualSession.Name); } [Fact] public async Task RenameChatSessionAsync_ShouldThrowExceptionWhenSessionIdIsNull() { // Arrange - var newChatSessionName = "NewName"; + var chatSessionProperties = new ChatSessionProperties() { Name = "NewName" }; // Assert await Assert.ThrowsAsync(async () => { - await _testedService.RenameChatSessionAsync(_instanceId, null!, newChatSessionName); + await _testedService.RenameChatSessionAsync(_instanceId, null!, chatSessionProperties); }); } @@ -197,7 +199,7 @@ await Assert.ThrowsAsync(async () => await Assert.ThrowsAsync(async () => { - await _testedService.RenameChatSessionAsync(_instanceId, sessionId, string.Empty); + await _testedService.RenameChatSessionAsync(_instanceId, sessionId, new ChatSessionProperties() { Name = string.Empty }); }); } @@ -309,76 +311,6 @@ public async Task GetChatCompletionAsync_ShouldNotThrowExceptionWhenSessionIdIsN #endregion - #region SetChatSessionNameAsync - - [Fact] - public async Task SummarizeChatSessionNameAsync_ShouldReturnACompletion() - { - // Arrange - var sessionId = Guid.NewGuid().ToString(); - var prompt = "Prompt"; - var summary = "[No Summary]"; - var summaryRequest = new SummaryRequest - { - SessionId = sessionId, - UserPrompt = prompt - }; - var expectedCompletion = new Completion() { Text = summary }; - - - _cosmosDbService.UpdateSessionNameAsync(sessionId, summary).Returns(new Session()); - - // Act - var actualCompletion = await _testedService.GenerateChatSessionNameAsync(_instanceId, sessionId, prompt); - - // Assert - Assert.Equal(expectedCompletion.Text, actualCompletion.Text); - } - - [Fact] - public async Task SummarizeChatSessionNameAsync_ShouldReturnAnErrorMessageWhenSessionIdIsNull() - { - // Arrange - var prompt = "Prompt"; - var expectedCompletion = new Completion { Text = "[No Summary]" }; - - // Act - var actualSummary = await _testedService.GenerateChatSessionNameAsync(_instanceId, null, prompt); - - // Assert - Assert.Equal(expectedCompletion.Text, actualSummary.Text); - - //_logger.Received(1).LogError($"Error getting a summary in session {sessionId} for user prompt [{prompt}]."); - } - - [Fact] - public async Task SummarizeChatSessionNameAsync_ShouldNotThrowExceptionWhenPromptIsNull() - { - // Arrange - var sessionId = Guid.NewGuid().ToString(); - - // Act - var exception = await Record.ExceptionAsync(async () => await _testedService.GenerateChatSessionNameAsync(_instanceId, sessionId, null!)); - - // Assert - Assert.Null(exception); - } - - [Fact] - public async Task SummarizeChatSessionNameAsync_ShouldNotThrowExceptionWhenSessionIdIsNull() - { - // Arrange - var prompt = "Prompt"; - - // Act - var exception = await Record.ExceptionAsync(async () => await _testedService.GenerateChatSessionNameAsync(_instanceId, null, prompt)); - - // Assert - Assert.Null(exception); - } - - #endregion - #region RateMessageAsync [Fact] diff --git a/tests/dotnet/Core.Tests/Services/GatekeeperAPIServiceTests.cs b/tests/dotnet/Core.Tests/Services/GatekeeperAPIServiceTests.cs index 93f80250e0..ee9cff9bb2 100644 --- a/tests/dotnet/Core.Tests/Services/GatekeeperAPIServiceTests.cs +++ b/tests/dotnet/Core.Tests/Services/GatekeeperAPIServiceTests.cs @@ -13,11 +13,12 @@ public class GatekeeperAPIServiceTests private readonly string _instanceId = "00000000-0000-0000-0000-000000000000"; private readonly GatekeeperAPIService _testedService; + private readonly ICallContext _callContext = Substitute.For(); private readonly IHttpClientFactoryService _httpClientFactoryService = Substitute.For(); public GatekeeperAPIServiceTests() { - _testedService = new GatekeeperAPIService(_httpClientFactoryService); + _testedService = new GatekeeperAPIService(_callContext, _httpClientFactoryService); } #region GetCompletion @@ -35,7 +36,7 @@ public async Task GetCompletion_SuccessfulCompletionResponse() { BaseAddress = new Uri("http://nsubstitute.io") }; - _httpClientFactoryService.CreateClient(Arg.Any()).Returns(httpClient); + _httpClientFactoryService.CreateClient(Arg.Any(), _callContext.CurrentUserIdentity).Returns(httpClient); // Act var actual = await _testedService.GetCompletion(_instanceId, completionRequest); @@ -58,7 +59,7 @@ public async Task GetCompletion_UnsuccessfulDefaultResponse() { BaseAddress = new Uri("http://nsubstitute.io") }; - _httpClientFactoryService.CreateClient(Arg.Any()).Returns(httpClient); + _httpClientFactoryService.CreateClient(Arg.Any(), _callContext.CurrentUserIdentity).Returns(httpClient); // Act var actual = await _testedService.GetCompletion(_instanceId, completionRequest);