diff --git a/dotnet/SK-dotnet.sln b/dotnet/SK-dotnet.sln
index 45273e9ad18c..86b0ceb3d3a5 100644
--- a/dotnet/SK-dotnet.sln
+++ b/dotnet/SK-dotnet.sln
@@ -140,8 +140,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plugins.Core", "src\Plugins
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NCalcPlugins", "samples\NCalcPlugins\NCalcPlugins.csproj", "{E6EDAB8F-3406-4DBF-9AAB-DF40DC2CA0FA}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connectors.AI.Oobabooga", "src\Connectors\Connectors.AI.Oobabooga\Connectors.AI.Oobabooga.csproj", "{677F1381-7830-4115-9C1A-58B282629DC6}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ApplicationInsightsExample", "samples\ApplicationInsightsExample\ApplicationInsightsExample.csproj", "{C754950A-E16C-4F96-9CC7-9328E361B5AF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Connectors.Memory.Kusto", "src\Connectors\Connectors.Memory.Kusto\Connectors.Memory.Kusto.csproj", "{E07608CC-D710-4655-BB9E-D22CF3CDD193}"
@@ -348,12 +346,6 @@ Global
{E6EDAB8F-3406-4DBF-9AAB-DF40DC2CA0FA}.Publish|Any CPU.ActiveCfg = Release|Any CPU
{E6EDAB8F-3406-4DBF-9AAB-DF40DC2CA0FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E6EDAB8F-3406-4DBF-9AAB-DF40DC2CA0FA}.Release|Any CPU.Build.0 = Release|Any CPU
- {677F1381-7830-4115-9C1A-58B282629DC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {677F1381-7830-4115-9C1A-58B282629DC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {677F1381-7830-4115-9C1A-58B282629DC6}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
- {677F1381-7830-4115-9C1A-58B282629DC6}.Publish|Any CPU.Build.0 = Publish|Any CPU
- {677F1381-7830-4115-9C1A-58B282629DC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {677F1381-7830-4115-9C1A-58B282629DC6}.Release|Any CPU.Build.0 = Release|Any CPU
{C754950A-E16C-4F96-9CC7-9328E361B5AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C754950A-E16C-4F96-9CC7-9328E361B5AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C754950A-E16C-4F96-9CC7-9328E361B5AF}.Publish|Any CPU.ActiveCfg = Release|Any CPU
@@ -460,7 +452,6 @@ Global
{3CDE10B2-AE8F-4FC4-8D55-92D4AD32E144} = {958AD708-F048-4FAF-94ED-D2F2B92748B9}
{0D0C4DAD-E6BC-4504-AE3A-EEA4E35920C1} = {D6D598DF-C17C-46F4-B2B9-CDE82E2DE132}
{E6EDAB8F-3406-4DBF-9AAB-DF40DC2CA0FA} = {FA3720F1-C99A-49B2-9577-A940257098BF}
- {677F1381-7830-4115-9C1A-58B282629DC6} = {0247C2C9-86C3-45BA-8873-28B0948EDC0C}
{C754950A-E16C-4F96-9CC7-9328E361B5AF} = {FA3720F1-C99A-49B2-9577-A940257098BF}
{E07608CC-D710-4655-BB9E-D22CF3CDD193} = {0247C2C9-86C3-45BA-8873-28B0948EDC0C}
{10E4B697-D4E8-468D-872D-49670FD150FB} = {078F96B4-09E1-4E0E-B214-F71A4F4BF633}
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/Connectors.AI.Oobabooga.csproj b/dotnet/src/Connectors/Connectors.AI.Oobabooga/Connectors.AI.Oobabooga.csproj
deleted file mode 100644
index f55b818e10d8..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/Connectors.AI.Oobabooga.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
- Microsoft.SemanticKernel.Connectors.AI.Oobabooga
- $(AssemblyName)
- netstandard2.0
-
-
-
-
-
-
-
-
- Semantic Kernel - Oobabooga Connector
- Semantic Kernel connector for the oobabooga text-generation-webui open source project. Contains a client for text completion.
-
-
-
-
-
-
-
-
-
-
-
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/README.md b/dotnet/src/Connectors/Connectors.AI.Oobabooga/README.md
new file mode 100644
index 000000000000..b1c45cd528cd
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.AI.Oobabooga/README.md
@@ -0,0 +1,3 @@
+# Semantic Kernel Oobabooga AI Connector
+
+This connector have moved, please go [here](https://github.com/MyIntelligenceAgency/semantic-fleet) for more information.
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/OobaboogaTextCompletion.cs b/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/OobaboogaTextCompletion.cs
deleted file mode 100644
index 6a0ee2174b46..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/OobaboogaTextCompletion.cs
+++ /dev/null
@@ -1,481 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net.Http;
-using System.Net.WebSockets;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Microsoft.SemanticKernel.AI;
-using Microsoft.SemanticKernel.AI.TextCompletion;
-using Microsoft.SemanticKernel.Diagnostics;
-
-namespace Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-///
-/// Oobabooga text completion service API.
-/// Adapted from
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class OobaboogaTextCompletion : ITextCompletion
-{
- ///
- /// The URI path for blocking API requests.
- ///
- public const string BlockingUriPath = "/api/v1/generate";
- private const string StreamingUriPath = "/api/v1/stream";
-
- private readonly UriBuilder _blockingUri;
- private readonly UriBuilder _streamingUri;
- private readonly HttpClient _httpClient;
- private readonly Func _webSocketFactory;
- private readonly bool _useWebSocketsPooling;
- private readonly int _maxNbConcurrentWebSockets;
- private readonly SemaphoreSlim? _concurrentSemaphore;
- private readonly ConcurrentBag? _activeConnections;
- private readonly ConcurrentBag _webSocketPool = new();
- private readonly int _keepAliveWebSocketsDuration;
- private readonly ILogger? _logger;
- private Task? _cleanupTask = null;
- private long _lastCallTicks = long.MaxValue;
-
- ///
- /// Controls the size of the buffer used to receive websocket packets.
- ///
- public int WebSocketBufferSize { get; set; } = 2048;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The service API endpoint to which requests should be sent.
- /// The port used for handling blocking requests. Default value is 5000
- /// The port used for handling streaming requests. Default value is 5005
- /// You can optionally set a hard limit on the max number of concurrent calls to the either of the completion methods by providing a . Calls in excess will wait for existing consumers to release the semaphore
- /// Optional. The HTTP client used for making blocking API requests. If not specified, a default client will be used.
- /// If true, websocket clients will be recycled in a reusable pool as long as concurrent calls are detected
- /// if websocket pooling is enabled, you can provide an optional CancellationToken to properly dispose of the clean up tasks when disposing of the connector
- /// When pooling is enabled, pooled websockets are flushed on a regular basis when no more connections are made. This is the time to keep them in pool before flushing
- /// The WebSocket factory used for making streaming API requests. Note that only when pooling is enabled will websocket be recycled and reused for the specified duration. Otherwise, a new websocket is created for each call and closed and disposed afterwards, to prevent data corruption from concurrent calls.
- /// Application logger
- public OobaboogaTextCompletion(Uri endpoint,
- int blockingPort = 5000,
- int streamingPort = 5005,
- SemaphoreSlim? concurrentSemaphore = null,
- HttpClient? httpClient = null,
- bool useWebSocketsPooling = true,
- CancellationToken? webSocketsCleanUpCancellationToken = default,
- int keepAliveWebSocketsDuration = 100,
- Func? webSocketFactory = null,
- ILogger? logger = null)
- {
- Verify.NotNull(endpoint);
- this._blockingUri = new UriBuilder(endpoint)
- {
- Port = blockingPort,
- Path = BlockingUriPath
- };
- this._streamingUri = new(endpoint)
- {
- Port = streamingPort,
- Path = StreamingUriPath
- };
- if (this._streamingUri.Uri.Scheme.StartsWith("http", StringComparison.OrdinalIgnoreCase))
- {
- this._streamingUri.Scheme = (this._streamingUri.Scheme == "https") ? "wss" : "ws";
- }
-
- this._httpClient = httpClient ?? new HttpClient(NonDisposableHttpClientHandler.Instance, disposeHandler: false);
- this._useWebSocketsPooling = useWebSocketsPooling;
- this._keepAliveWebSocketsDuration = keepAliveWebSocketsDuration;
- this._logger = logger;
- if (webSocketFactory != null)
- {
- this._webSocketFactory = () =>
- {
- var webSocket = webSocketFactory();
- this.SetWebSocketOptions(webSocket);
- return webSocket;
- };
- }
- else
- {
- this._webSocketFactory = () =>
- {
- ClientWebSocket webSocket = new();
- this.SetWebSocketOptions(webSocket);
- return webSocket;
- };
- }
-
- // if a hard limit is defined, we use a semaphore to limit the number of concurrent calls, otherwise, we use a stack to track active connections
- if (concurrentSemaphore != null)
- {
- this._concurrentSemaphore = concurrentSemaphore;
- this._maxNbConcurrentWebSockets = concurrentSemaphore.CurrentCount;
- }
- else
- {
- this._activeConnections = new();
- this._maxNbConcurrentWebSockets = 0;
- }
-
- if (this._useWebSocketsPooling)
- {
- this.StartCleanupTask(webSocketsCleanUpCancellationToken ?? CancellationToken.None);
- }
- }
-
- ///
- public async IAsyncEnumerable GetStreamingCompletionsAsync(
- string text,
- AIRequestSettings? requestSettings = null,
- [EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- await this.StartConcurrentCallAsync(cancellationToken).ConfigureAwait(false);
-
- var completionRequest = this.CreateOobaboogaRequest(text, requestSettings);
-
- var requestJson = JsonSerializer.Serialize(completionRequest);
-
- var requestBytes = Encoding.UTF8.GetBytes(requestJson);
-
- ClientWebSocket? clientWebSocket = null;
- try
- {
- // if pooling is enabled, web socket is going to be recycled for reuse, if not it will be properly disposed of after the call
-#pragma warning disable CA2000 // Dispose objects before losing scope
- if (!this._useWebSocketsPooling || !this._webSocketPool.TryTake(out clientWebSocket))
- {
- clientWebSocket = this._webSocketFactory();
- }
-#pragma warning restore CA2000 // Dispose objects before losing scope
- if (clientWebSocket.State == WebSocketState.None)
- {
- await clientWebSocket.ConnectAsync(this._streamingUri.Uri, cancellationToken).ConfigureAwait(false);
- }
-
- var sendSegment = new ArraySegment(requestBytes);
- await clientWebSocket.SendAsync(sendSegment, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);
-
- TextCompletionStreamingResult streamingResult = new();
-
- var processingTask = this.ProcessWebSocketMessagesAsync(clientWebSocket, streamingResult, cancellationToken);
-
- yield return streamingResult;
-
- // Await the processing task to make sure it's finished before continuing
- await processingTask.ConfigureAwait(false);
- }
- finally
- {
- if (clientWebSocket != null)
- {
- if (this._useWebSocketsPooling && clientWebSocket.State == WebSocketState.Open)
- {
- this._webSocketPool.Add(clientWebSocket);
- }
- else
- {
- await this.DisposeClientGracefullyAsync(clientWebSocket).ConfigureAwait(false);
- }
- }
-
- this.FinishConcurrentCall();
- }
- }
-
- ///
- public async Task> GetCompletionsAsync(
- string text,
- AIRequestSettings? requestSettings = null,
- CancellationToken cancellationToken = default)
- {
- try
- {
- await this.StartConcurrentCallAsync(cancellationToken).ConfigureAwait(false);
-
- var completionRequest = this.CreateOobaboogaRequest(text, requestSettings);
-
- using var stringContent = new StringContent(
- JsonSerializer.Serialize(completionRequest),
- Encoding.UTF8,
- "application/json");
-
- using var httpRequestMessage = new HttpRequestMessage()
- {
- Method = HttpMethod.Post,
- RequestUri = this._blockingUri.Uri,
- Content = stringContent
- };
- httpRequestMessage.Headers.Add("User-Agent", Telemetry.HttpUserAgent);
-
- using var response = await this._httpClient.SendWithSuccessCheckAsync(httpRequestMessage, cancellationToken).ConfigureAwait(false);
-
- var body = await response.Content.ReadAsStringWithExceptionMappingAsync().ConfigureAwait(false);
-
- TextCompletionResponse? completionResponse = JsonSerializer.Deserialize(body);
-
- if (completionResponse is null)
- {
- throw new SKException($"Unexpected response from Oobabooga API: {body}");
- }
-
- return completionResponse.Results.Select(completionText => new TextCompletionResult(completionText)).ToList();
- }
- finally
- {
- this.FinishConcurrentCall();
- }
- }
-
- #region private ================================================================================
-
- ///
- /// Creates an Oobabooga request, mapping dynamic request setting fields to their Oobabooga API counter parts
- ///
- /// The text to complete.
- /// The request settings.
- /// An Oobabooga TextCompletionRequest object with the text and completion parameters.
- private TextCompletionRequest CreateOobaboogaRequest(string text, AIRequestSettings? requestSettings)
- {
- if (string.IsNullOrWhiteSpace(text))
- {
- throw new ArgumentNullException(nameof(text));
- }
-
- if (requestSettings is null)
- {
- return new TextCompletionRequest()
- {
- Prompt = text
- };
- }
-
- if (requestSettings is TextCompletionRequest requestSettingsTextCompletionRequest)
- {
- requestSettingsTextCompletionRequest.Prompt = text;
- return requestSettingsTextCompletionRequest;
- }
-
- var json = JsonSerializer.Serialize(requestSettings);
- var textCompletionRequest = JsonSerializer.Deserialize(json);
-
- if (textCompletionRequest is not null)
- {
- textCompletionRequest.Prompt = text;
- return textCompletionRequest;
- }
-
- throw new ArgumentException("Invalid request settings, cannot convert to TextCompletionRequest", nameof(requestSettings));
- }
-
- ///
- /// Sets the options for the , either persistent and provided by the ctor, or transient if none provided.
- ///
- private void SetWebSocketOptions(ClientWebSocket clientWebSocket)
- {
- clientWebSocket.Options.SetRequestHeader("User-Agent", Telemetry.HttpUserAgent);
- }
-
- ///
- /// That method is responsible for processing the websocket messages that build a streaming response object. It is crucial that it is run asynchronously to prevent a deadlock with results iteration
- ///
- private async Task ProcessWebSocketMessagesAsync(ClientWebSocket clientWebSocket, TextCompletionStreamingResult streamingResult, CancellationToken cancellationToken)
- {
- var buffer = new byte[this.WebSocketBufferSize];
- var finishedProcessing = false;
- while (!finishedProcessing && !cancellationToken.IsCancellationRequested)
- {
- MemoryStream messageStream = new();
- WebSocketReceiveResult result;
- do
- {
- var segment = new ArraySegment(buffer);
- result = await clientWebSocket.ReceiveAsync(segment, cancellationToken).ConfigureAwait(false);
- await messageStream.WriteAsync(buffer, 0, result.Count, cancellationToken).ConfigureAwait(false);
- } while (!result.EndOfMessage);
-
- messageStream.Seek(0, SeekOrigin.Begin);
-
- if (result.MessageType == WebSocketMessageType.Text)
- {
- string messageText;
- using (var reader = new StreamReader(messageStream, Encoding.UTF8))
- {
- messageText = await reader.ReadToEndAsync().ConfigureAwait(false);
- }
-
- var responseObject = JsonSerializer.Deserialize(messageText);
-
- if (responseObject is null)
- {
- throw new SKException($"Unexpected response from Oobabooga API: {messageText}");
- }
-
- switch (responseObject.Event)
- {
- case TextCompletionStreamingResponse.ResponseObjectTextStreamEvent:
- streamingResult.AppendResponse(responseObject);
- break;
- case TextCompletionStreamingResponse.ResponseObjectStreamEndEvent:
- streamingResult.SignalStreamEnd();
- if (!this._useWebSocketsPooling)
- {
- await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Acknowledge stream-end oobabooga message", CancellationToken.None).ConfigureAwait(false);
- }
-
- finishedProcessing = true;
- break;
- default:
- break;
- }
- }
- else if (result.MessageType == WebSocketMessageType.Close)
- {
- await clientWebSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Acknowledge Close frame", CancellationToken.None).ConfigureAwait(false);
- finishedProcessing = true;
- }
-
- if (clientWebSocket.State != WebSocketState.Open)
- {
- finishedProcessing = true;
- }
- }
- }
-
- ///
- /// Starts a concurrent call, either by taking a semaphore slot or by pushing a value on the active connections stack
- ///
- ///
- private async Task StartConcurrentCallAsync(CancellationToken cancellationToken)
- {
- if (this._concurrentSemaphore != null)
- {
- await this._concurrentSemaphore!.WaitAsync(cancellationToken).ConfigureAwait(false);
- }
- else
- {
- this._activeConnections!.Add(true);
- }
- }
-
- ///
- /// Gets the number of concurrent calls, either by reading the semaphore count or by reading the active connections stack count
- ///
- ///
- private int GetCurrentConcurrentCallsNb()
- {
- if (this._concurrentSemaphore != null)
- {
- return this._maxNbConcurrentWebSockets - this._concurrentSemaphore!.CurrentCount;
- }
-
- return this._activeConnections!.Count;
- }
-
- ///
- /// Ends a concurrent call, either by releasing a semaphore slot or by popping a value from the active connections stack
- ///
- private void FinishConcurrentCall()
- {
- if (this._concurrentSemaphore != null)
- {
- this._concurrentSemaphore!.Release();
- }
- else
- {
- this._activeConnections!.TryTake(out _);
- }
-
- Interlocked.Exchange(ref this._lastCallTicks, DateTime.UtcNow.Ticks);
- }
-
- private void StartCleanupTask(CancellationToken cancellationToken)
- {
- if (this._cleanupTask == null || this._cleanupTask.IsCompleted)
- {
- this._cleanupTask = Task.Factory.StartNew(
- async () =>
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- await this.FlushWebSocketClientsAsync(cancellationToken).ConfigureAwait(false);
- }
- },
- cancellationToken,
- TaskCreationOptions.LongRunning,
- TaskScheduler.Default);
- }
- }
-
- ///
- /// Flushes the web socket clients that have been idle for too long
- ///
- ///
- private async Task FlushWebSocketClientsAsync(CancellationToken cancellationToken)
- {
- // In the cleanup task, make sure you handle OperationCanceledException appropriately
- // and make frequent checks on whether cancellation is requested.
- try
- {
- if (!cancellationToken.IsCancellationRequested)
- {
- await Task.Delay(this._keepAliveWebSocketsDuration, cancellationToken).ConfigureAwait(false);
-
- // If another call was made during the delay, do not proceed with flushing
- if (DateTime.UtcNow.Ticks - Interlocked.Read(ref this._lastCallTicks) < TimeSpan.FromMilliseconds(this._keepAliveWebSocketsDuration).Ticks)
- {
- return;
- }
-
- while (this.GetCurrentConcurrentCallsNb() == 0 && this._webSocketPool.TryTake(out ClientWebSocket clientToDispose))
- {
- await this.DisposeClientGracefullyAsync(clientToDispose).ConfigureAwait(false);
- }
- }
- }
- catch (OperationCanceledException exception)
- {
- this._logger?.LogTrace(message: "FlushWebSocketClientsAsync cleaning task was cancelled", exception: exception);
- while (this._webSocketPool.TryTake(out ClientWebSocket clientToDispose))
- {
- await this.DisposeClientGracefullyAsync(clientToDispose).ConfigureAwait(false);
- }
- }
- }
-
- ///
- /// Closes and disposes of a client web socket after use
- ///
- private async Task DisposeClientGracefullyAsync(ClientWebSocket clientWebSocket)
- {
- try
- {
- if (clientWebSocket.State == WebSocketState.Open)
- {
- await clientWebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing client before disposal", CancellationToken.None).ConfigureAwait(false);
- }
- }
- catch (OperationCanceledException exception)
- {
- this._logger?.LogTrace(message: "Closing client web socket before disposal was cancelled", exception: exception);
- }
- catch (WebSocketException exception)
- {
- this._logger?.LogTrace(message: "Closing client web socket before disposal raised web socket exception", exception: exception);
- }
- finally
- {
- clientWebSocket.Dispose();
- }
- }
-
- #endregion
-}
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionRequest.cs b/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionRequest.cs
deleted file mode 100644
index 0b64735a4683..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionRequest.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-using Microsoft.SemanticKernel.AI;
-
-namespace Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-///
-/// HTTP schema to perform oobabooga completion request. Contains many parameters, some of which are specific to certain kinds of models.
-/// See and subsequent links for additional information.
-///
-[Serializable]
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class TextCompletionRequest : AIRequestSettings
-{
- ///
- /// The prompt text to complete.
- ///
- [JsonPropertyName("prompt")]
- public string Prompt { get; set; } = string.Empty;
-
- ///
- /// The maximum number of tokens to generate, ignoring the number of tokens in the prompt.
- ///
- [JsonPropertyName("max_new_tokens")]
- public int? MaxNewTokens { get; set; }
-
- ///
- /// Determines whether or not to use sampling; use greedy decoding if false.
- ///
- [JsonPropertyName("do_sample")]
- public bool DoSample { get; set; } = true;
-
- ///
- /// Modulates the next token probabilities. A value of 0 implies deterministic output (only the most likely token is used). Higher values increase randomness.
- ///
- [JsonPropertyName("temperature")]
- public double Temperature { get; set; }
-
- ///
- /// If set to a value less than 1, only the most probable tokens with cumulative probability less than this value are kept for generation.
- ///
- [JsonPropertyName("top_p")]
- public double TopP { get; set; }
-
- ///
- /// Measures how similar the conditional probability of predicting a target token is to the expected conditional probability of predicting a random token, given the generated text.
- ///
- [JsonPropertyName("typical_p")]
- public double TypicalP { get; set; } = 1;
-
- ///
- /// Sets a probability floor below which tokens are excluded from being sampled.
- ///
- [JsonPropertyName("epsilon_cutoff")]
- public double EpsilonCutoff { get; set; }
-
- ///
- /// Used with top_p, top_k, and epsilon_cutoff set to 0. This parameter hybridizes locally typical sampling and epsilon sampling.
- ///
- [JsonPropertyName("eta_cutoff")]
- public double EtaCutoff { get; set; }
-
- ///
- /// Controls Tail Free Sampling (value between 0 and 1)
- ///
- [JsonPropertyName("tfs")]
- public double Tfs { get; set; } = 1;
-
- ///
- /// Top A Sampling is a way to pick the next word in a sentence based on how important it is in the context. Top-A considers the probability of the most likely token, and sets a limit based on its percentage. After this, remaining tokens are compared to this limit. If their probability is too low, they are removed from the pool.
- ///
- [JsonPropertyName("top_a")]
- public double TopA { get; set; }
-
- ///
- /// Exponential penalty factor for repeating prior tokens. 1 means no penalty, higher value = less repetition.
- ///
- [JsonPropertyName("repetition_penalty")]
- public double RepetitionPenalty { get; set; } = 1.18;
-
- ///
- ///When using "top k", you select the top k most likely words to come next based on their probability of occurring, where k is a fixed number that you specify. You can use Top_K to control the amount of diversity in the model output
- ///
- [JsonPropertyName("top_k")]
- public int TopK { get; set; }
-
- ///
- /// Minimum length of the sequence to be generated.
- ///
- [JsonPropertyName("min_length")]
- public int MinLength { get; set; }
-
- ///
- /// If set to a value greater than 0, all ngrams of that size can only occur once.
- ///
- [JsonPropertyName("no_repeat_ngram_size")]
- public int NoRepeatNgramSize { get; set; }
-
- ///
- /// Number of beams for beam search. 1 means no beam search.
- ///
- [JsonPropertyName("num_beams")]
- public int NumBeams { get; set; } = 1;
-
- ///
- /// The values balance the model confidence and the degeneration penalty in contrastive search decoding.
- ///
- [JsonPropertyName("penalty_alpha")]
- public int PenaltyAlpha { get; set; }
-
- ///
- /// Exponential penalty to the length that is used with beam-based generation
- ///
- [JsonPropertyName("length_penalty")]
- public double LengthPenalty { get; set; } = 1;
-
- ///
- /// Controls the stopping condition for beam-based methods, like beam-search. It accepts the following values: True, where the generation stops as soon as there are num_beams complete candidates; False, where an heuristic is applied and the generation stops when is it very unlikely to find better candidates.
- ///
- [JsonPropertyName("early_stopping")]
- public bool EarlyStopping { get; set; }
-
- ///
- /// Parameter used for mirostat sampling in Llama.cpp, controlling perplexity during text (default: 0, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0)
- ///
- [JsonPropertyName("mirostat_mode")]
- public int MirostatMode { get; set; }
-
- ///
- /// Set the Mirostat target entropy, parameter tau (default: 5.0)
- ///
- [JsonPropertyName("mirostat_tau")]
- public int MirostatTau { get; set; } = 5;
-
- ///
- /// Set the Mirostat learning rate, parameter eta (default: 0.1)
- ///
- [JsonPropertyName("mirostat_eta")]
- public double MirostatEta { get; set; } = 0.1;
-
- ///
- /// Random seed to control sampling, used when DoSample is True.
- ///
- [JsonPropertyName("seed")]
- public int Seed { get; set; } = -1;
-
- ///
- /// Controls whether to add beginning of a sentence token
- ///
- [JsonPropertyName("add_bos_token")]
- public bool AddBosToken { get; set; } = true;
-
- ///
- /// The leftmost tokens are removed if the prompt exceeds this length. Most models require this to be at most 2048.
- ///
- [JsonPropertyName("truncation_length")]
- public int TruncationLength { get; set; } = 2048;
-
- ///
- /// Forces the model to never end the generation prematurely.
- ///
- [JsonPropertyName("ban_eos_token")]
- public bool BanEosToken { get; set; } = true;
-
- ///
- /// Some specific models need this unset.
- ///
- [JsonPropertyName("skip_special_tokens")]
- public bool SkipSpecialTokens { get; set; } = true;
-
- ///
- /// In addition to the defaults. Written between "" and separated by commas. For instance: "\nYour Assistant:", "\nThe assistant:"
- ///
- [JsonPropertyName("stopping_strings")]
- public IList StoppingStrings { get; set; } = new List();
-}
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionResponse.cs b/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionResponse.cs
deleted file mode 100644
index ac3a60ad20a1..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionResponse.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-///
-/// HTTP Schema for Oobabooga completion response. Contains a list of results. Adapted from
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class TextCompletionResponse
-{
- ///
- /// A field used by Oobabooga to return results from the blocking API.
- ///
- [JsonPropertyName("results")]
- public List Results { get; set; } = new();
-}
-
-///
-/// HTTP Schema for an single Oobabooga result as part of a completion response.
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class TextCompletionResponseText
-{
- ///
- /// Completed text.
- ///
- [JsonPropertyName("text")]
- public string? Text { get; set; } = string.Empty;
-}
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionResult.cs b/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionResult.cs
deleted file mode 100644
index 8961b758faf7..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionResult.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.SemanticKernel.AI.TextCompletion;
-using Microsoft.SemanticKernel.Orchestration;
-
-namespace Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-///
-/// Oobabooga implementation of . Actual response object is stored in a ModelResult instance, and completion text is simply passed forward.
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-internal sealed class TextCompletionResult : ITextResult
-{
- private readonly ModelResult _responseData;
-
- public TextCompletionResult(TextCompletionResponseText responseData)
- {
- this._responseData = new ModelResult(responseData);
- }
-
- public ModelResult ModelResult => this._responseData;
-
- public Task GetCompletionAsync(CancellationToken cancellationToken = default)
- {
- return Task.FromResult(this._responseData.GetResult().Text ?? string.Empty);
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionStreamingResponse.cs b/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionStreamingResponse.cs
deleted file mode 100644
index 3951b638e962..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionStreamingResponse.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Text.Json.Serialization;
-
-namespace Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-///
-/// Represents the HTTP schema for streaming completion response. Adapted from .
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class TextCompletionStreamingResponse
-{
- ///
- /// Constant string representing the event that is fired when text is received from a websocket.
- ///
- public const string ResponseObjectTextStreamEvent = "text_stream";
-
- ///
- /// Constant string representing the event that is fired when streaming from a websocket ends.
- ///
- public const string ResponseObjectStreamEndEvent = "stream_end";
-
- ///
- /// A field used by Oobabooga to signal the type of websocket message sent, e.g. "text_stream" or "stream_end".
- ///
- [JsonPropertyName("event")]
- public string Event { get; set; } = string.Empty;
-
- ///
- /// A field used by Oobabooga to signal the number of messages sent, starting with 0 and incremented on each message.
- ///
- [JsonPropertyName("message_num")]
- public int MessageNum { get; set; }
-
- ///
- /// A field used by Oobabooga with the text chunk sent in the websocket message.
- ///
- [JsonPropertyName("text")]
- public string Text { get; set; } = string.Empty;
-}
diff --git a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionStreamingResult.cs b/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionStreamingResult.cs
deleted file mode 100644
index e780d45cd62e..000000000000
--- a/dotnet/src/Connectors/Connectors.AI.Oobabooga/TextCompletion/TextCompletionStreamingResult.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading;
-using System.Threading.Channels;
-using System.Threading.Tasks;
-using Microsoft.SemanticKernel.AI.TextCompletion;
-using Microsoft.SemanticKernel.Orchestration;
-
-namespace Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-internal sealed class TextCompletionStreamingResult : ITextStreamingResult, ITextResult
-{
- private readonly List _modelResponses;
- private readonly Channel _responseChannel;
-
- public ModelResult ModelResult { get; }
-
- public TextCompletionStreamingResult()
- {
- this._modelResponses = new();
- this.ModelResult = new ModelResult(this._modelResponses);
- this._responseChannel = Channel.CreateUnbounded(new UnboundedChannelOptions()
- {
- SingleReader = true,
- SingleWriter = true,
- AllowSynchronousContinuations = false
- });
- }
-
- public void AppendResponse(TextCompletionStreamingResponse response)
- {
- this._modelResponses.Add(response);
- this._responseChannel.Writer.TryWrite(response.Text);
- }
-
- public void SignalStreamEnd()
- {
- this._responseChannel.Writer.Complete();
- }
-
- public async Task GetCompletionAsync(CancellationToken cancellationToken = default)
- {
- StringBuilder resultBuilder = new();
-
- await foreach (var chunk in this.GetCompletionStreamingAsync(cancellationToken))
- {
- resultBuilder.Append(chunk);
- }
-
- return resultBuilder.ToString();
- }
-
- public async IAsyncEnumerable GetCompletionStreamingAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- while (await this._responseChannel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false))
- {
- while (this._responseChannel.Reader.TryRead(out string? chunk))
- {
- yield return chunk;
- }
- }
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/ConnectedClient.cs b/dotnet/src/Connectors/Connectors.UnitTests/ConnectedClient.cs
deleted file mode 100644
index b47c192dbd61..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/ConnectedClient.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Net;
-using System.Net.WebSockets;
-
-namespace SemanticKernel.Connectors.UnitTests;
-
-internal sealed class ConnectedClient
-{
- public Guid Id { get; }
- public HttpListenerContext Context { get; }
- public WebSocket? Socket { get; private set; }
-
- public ConnectedClient(Guid id, HttpListenerContext context)
- {
- this.Id = id;
- this.Context = context;
- }
-
- public void SetSocket(WebSocket socket)
- {
- this.Socket = socket;
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/Connectors.UnitTests.csproj b/dotnet/src/Connectors/Connectors.UnitTests/Connectors.UnitTests.csproj
index 7ec3d3599b19..748c53e46567 100644
--- a/dotnet/src/Connectors/Connectors.UnitTests/Connectors.UnitTests.csproj
+++ b/dotnet/src/Connectors/Connectors.UnitTests/Connectors.UnitTests.csproj
@@ -32,7 +32,6 @@
-
@@ -59,12 +58,6 @@
Always
-
- Always
-
-
- Always
-
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/OobaboogaTestHelper.cs b/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/OobaboogaTestHelper.cs
deleted file mode 100644
index 0df5eda9dd19..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/OobaboogaTestHelper.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System.IO;
-using System.Net.Http;
-using System.Threading;
-using System.Threading.Tasks;
-using Moq;
-using Moq.Protected;
-
-namespace SemanticKernel.Connectors.UnitTests.Oobabooga;
-
-///
-/// Helper for Oobabooga test purposes.
-///
-internal static class OobaboogaTestHelper
-{
- ///
- /// Reads test response from file for mocking purposes.
- ///
- /// Name of the file with test response.
- internal static string GetTestResponse(string fileName)
- {
- return File.ReadAllText($"./Oobabooga/TestData/{fileName}");
- }
-
- ///
- /// Returns mocked instance of .
- ///
- /// Message to return for mocked .
- internal static HttpClientHandler GetHttpClientHandlerMock(HttpResponseMessage httpResponseMessage)
- {
- var httpClientHandler = new Mock();
-
- httpClientHandler
- .Protected()
- .Setup>(
- "SendAsync",
- ItExpr.IsAny(),
- ItExpr.IsAny())
- .ReturnsAsync(httpResponseMessage);
-
- return httpClientHandler.Object;
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/OobaboogaWebSocketTestServer.cs b/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/OobaboogaWebSocketTestServer.cs
deleted file mode 100644
index 7a4608d4569b..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/OobaboogaWebSocketTestServer.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Text.Json;
-using Microsoft.Extensions.Logging;
-using Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-
-namespace SemanticKernel.Connectors.UnitTests.Oobabooga;
-
-///
-/// Represents a WebSocket test server specifically designed for the Oobabooga text completion service.
-/// It inherits from the base WebSocketTestServer class and handles Oobabooga-specific request and response classes.
-/// The server accepts WebSocket connections, receives requests, and generates responses based on the Oobabooga text completion logic.
-/// The OobaboogaWebSocketTestServer class uses a delegate to handle the request and response logic, allowing customization of the behavior.
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-internal sealed class OobaboogaWebSocketTestServer : WebSocketTestServer
-{
- public OobaboogaWebSocketTestServer(string url, Func> stringHandler, ILogger? logger = null)
- : base(url, bytes => HandleRequest(bytes, stringHandler), logger: logger)
- {
- }
-
- private static List> HandleRequest(ArraySegment request, Func> stringHandler)
- {
- var requestString = Encoding.UTF8.GetString(request.ToArray());
- var requestObj = JsonSerializer.Deserialize(requestString);
-
- var responseList = stringHandler(requestObj?.Prompt ?? string.Empty);
-
- var responseSegments = new List>();
- int messageNum = 0;
- foreach (var responseChunk in responseList)
- {
- var responseObj = new TextCompletionStreamingResponse
- {
- Event = "text_stream",
- MessageNum = messageNum,
- Text = responseChunk
- };
-
- var responseJson = JsonSerializer.Serialize(responseObj);
- var responseBytes = Encoding.UTF8.GetBytes(responseJson);
- responseSegments.Add(new ArraySegment(responseBytes));
-
- messageNum++;
- }
-
- var streamEndObj = new TextCompletionStreamingResponse
- {
- Event = "stream_end",
- MessageNum = messageNum
- };
-
- var streamEndJson = JsonSerializer.Serialize(streamEndObj);
- var streamEndBytes = Encoding.UTF8.GetBytes(streamEndJson);
- responseSegments.Add(new ArraySegment(streamEndBytes));
-
- return responseSegments;
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TestData/completion_test_response.json b/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TestData/completion_test_response.json
deleted file mode 100644
index 397ee62436d5..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TestData/completion_test_response.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "results": [
- {
- "text": "This is test completion response"
-
- }
- ]
-
-}
\ No newline at end of file
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TestData/completion_test_streaming_response.json b/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TestData/completion_test_streaming_response.json
deleted file mode 100644
index bf731d314094..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TestData/completion_test_streaming_response.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "event": "text_stream",
- "message_num": 0,
- "text": "This is test completion response"
-}
\ No newline at end of file
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TextCompletion/OobaboogaTextCompletionTests.cs b/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TextCompletion/OobaboogaTextCompletionTests.cs
deleted file mode 100644
index e9503a5915dd..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/Oobabooga/TextCompletion/OobaboogaTextCompletionTests.cs
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Linq;
-using System.Net.Http;
-using System.Net.WebSockets;
-using System.Text;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Microsoft.SemanticKernel.AI.TextCompletion;
-using Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-using Xunit;
-using Xunit.Abstractions;
-
-namespace SemanticKernel.Connectors.UnitTests.Oobabooga.TextCompletion;
-
-///
-/// Unit tests for class.
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class OobaboogaTextCompletionTests : IDisposable
-{
- private readonly XunitLogger _logger;
- private const string EndPoint = "https://fake-random-test-host";
- private const int BlockingPort = 1234;
- private const int StreamingPort = 2345;
- private const string CompletionText = "fake-test";
- private const string CompletionMultiText = "Hello, my name is";
-
- private readonly HttpMessageHandlerStub _messageHandlerStub;
- private readonly HttpClient _httpClient;
- private readonly Uri _endPointUri;
- private readonly string _streamCompletionResponseStub;
-
- public OobaboogaTextCompletionTests(ITestOutputHelper output)
- {
- this._logger = new XunitLogger(output);
- this._messageHandlerStub = new HttpMessageHandlerStub();
- this._messageHandlerStub.ResponseToReturn.Content = new StringContent(OobaboogaTestHelper.GetTestResponse("completion_test_response.json"));
- this._streamCompletionResponseStub = OobaboogaTestHelper.GetTestResponse("completion_test_streaming_response.json");
-
- this._httpClient = new HttpClient(this._messageHandlerStub, false);
- this._endPointUri = new Uri(EndPoint);
- }
-
- [Fact]
- public async Task UserAgentHeaderShouldBeUsedAsync()
- {
- //Arrange
- var sut = new OobaboogaTextCompletion(endpoint: this._endPointUri,
- blockingPort: BlockingPort,
- httpClient: this._httpClient,
- logger: this._logger);
-
- //Act
- await sut.GetCompletionsAsync(CompletionText, null);
-
- //Assert
- Assert.True(this._messageHandlerStub.RequestHeaders?.Contains("User-Agent"));
-
- var values = this._messageHandlerStub.RequestHeaders!.GetValues("User-Agent");
-
- var value = values.SingleOrDefault();
- Assert.Equal("Semantic-Kernel", value);
- }
-
- [Fact]
- public async Task ProvidedEndpointShouldBeUsedAsync()
- {
- //Arrange
- var sut = new OobaboogaTextCompletion(endpoint: this._endPointUri,
- blockingPort: BlockingPort,
- httpClient: this._httpClient,
- logger: this._logger);
-
- //Act
- await sut.GetCompletionsAsync(CompletionText, null);
-
- //Assert
- Assert.StartsWith(EndPoint, this._messageHandlerStub.RequestUri?.AbsoluteUri, StringComparison.OrdinalIgnoreCase);
- }
-
- [Fact]
- public async Task BlockingUrlShouldBeBuiltSuccessfullyAsync()
- {
- //Arrange
- var sut = new OobaboogaTextCompletion(endpoint: this._endPointUri,
- blockingPort: BlockingPort,
- httpClient: this._httpClient,
- logger: this._logger);
-
- //Act
- await sut.GetCompletionsAsync(CompletionText);
- var expectedUri = new UriBuilder(this._endPointUri)
- {
- Path = OobaboogaTextCompletion.BlockingUriPath,
- Port = BlockingPort
- };
-
- //Assert
- Assert.Equal(expectedUri.Uri, this._messageHandlerStub.RequestUri);
- }
-
- [Fact]
- public async Task ShouldSendPromptToServiceAsync()
- {
- //Arrange
- var sut = new OobaboogaTextCompletion(endpoint: this._endPointUri,
- blockingPort: BlockingPort,
- httpClient: this._httpClient,
- logger: this._logger);
-
- //Act
- await sut.GetCompletionsAsync(CompletionText, null);
-
- //Assert
- var requestPayload = JsonSerializer.Deserialize(this._messageHandlerStub.RequestContent);
- Assert.NotNull(requestPayload);
-
- Assert.Equal(CompletionText, requestPayload.Prompt);
- }
-
- [Fact]
- public async Task ShouldHandleServiceResponseAsync()
- {
- //Arrange
- var sut = new OobaboogaTextCompletion(endpoint: this._endPointUri,
- blockingPort: BlockingPort,
- httpClient: this._httpClient,
- logger: this._logger);
-
- //Act
- var result = await sut.GetCompletionsAsync(CompletionText, null);
-
- //Assert
- Assert.NotNull(result);
-
- var completions = result.SingleOrDefault();
- Assert.NotNull(completions);
-
- var completion = await completions.GetCompletionAsync();
- Assert.Equal("This is test completion response", completion);
- }
-
- [Fact]
- public async Task ShouldHandleStreamingServicePersistentWebSocketResponseAsync()
- {
- var requestMessage = CompletionText;
- var expectedResponse = new List { this._streamCompletionResponseStub };
- await this.RunWebSocketMultiPacketStreamingTestAsync(
- requestMessage: requestMessage,
- expectedResponse: expectedResponse,
- isPersistent: true);
- }
-
- [Fact]
- public async Task ShouldHandleStreamingServiceTransientWebSocketResponseAsync()
- {
- var requestMessage = CompletionText;
- var expectedResponse = new List { this._streamCompletionResponseStub };
- await this.RunWebSocketMultiPacketStreamingTestAsync(
- requestMessage: requestMessage,
- expectedResponse: expectedResponse);
- }
-
- [Fact]
- public async Task ShouldHandleConcurrentWebSocketConnectionsAsync()
- {
- var serverUrl = $"http://localhost:{StreamingPort}/";
- var clientUrl = $"ws://localhost:{StreamingPort}/";
- var expectedResponses = new List
- {
- "Response 1",
- "Response 2",
- "Response 3",
- "Response 4",
- "Response 5"
- };
-
- await using var server = new WebSocketTestServer(serverUrl, request =>
- {
- // Simulate different responses for each request
- var responseIndex = int.Parse(Encoding.UTF8.GetString(request.ToArray()), CultureInfo.InvariantCulture);
- byte[] bytes = Encoding.UTF8.GetBytes(expectedResponses[responseIndex]);
- var toReturn = new List> { new(bytes) };
- return toReturn;
- });
-
- var tasks = new List>();
-
- // Simulate multiple concurrent WebSocket connections
- for (int i = 0; i < expectedResponses.Count; i++)
- {
- var currentIndex = i;
- tasks.Add(Task.Run(async () =>
- {
- using var client = new ClientWebSocket();
- await client.ConnectAsync(new Uri(clientUrl), CancellationToken.None);
-
- // Send a request to the server
- var requestBytes = Encoding.UTF8.GetBytes(currentIndex.ToString(CultureInfo.InvariantCulture));
- await client.SendAsync(new ArraySegment(requestBytes), WebSocketMessageType.Text, true, CancellationToken.None);
-
- // Receive the response from the server
- var responseBytes = new byte[1024];
- var responseResult = await client.ReceiveAsync(new ArraySegment(responseBytes), CancellationToken.None);
- await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close connection after message received", CancellationToken.None);
-
- var response = Encoding.UTF8.GetString(responseBytes, 0, responseResult.Count);
-
- return response;
- }));
- }
-
- // Assert
- for (int i = 0; i < expectedResponses.Count; i++)
- {
- var response = await tasks[i];
- Assert.Equal(expectedResponses[i], response);
- }
- }
-
- [Fact]
- public async Task ShouldHandleMultiPacketStreamingServiceTransientWebSocketResponseAsync()
- {
- await this.RunWebSocketMultiPacketStreamingTestAsync();
- }
-
- [Fact]
- public async Task ShouldHandleMultiPacketStreamingServicePersistentWebSocketResponseBroadcastBlockAsync()
- {
- await this.RunWebSocketMultiPacketStreamingTestAsync(isPersistent: true);
- }
-
- [Fact]
- public async Task ShouldHandleConcurrentMultiPacketStreamingServiceTransientWebSocketResponseAsync()
- {
- await this.RunWebSocketMultiPacketStreamingTestAsync(nbConcurrentCalls: 10);
- }
-
- [Fact]
- public async Task ShouldHandleConcurrentMultiPacketStreamingServicePersistentWebSocketResponseAsync()
- {
- await this.RunWebSocketMultiPacketStreamingTestAsync(nbConcurrentCalls: 10, isPersistent: true);
- }
-
- ///
- /// This test will assess concurrent enumeration of the same long multi message (500 websocket messages) streaming result.
- ///
- [Fact]
- public async Task ShouldHandleConcurrentEnumerationOfLongStreamingServiceResponseAsync()
- {
- var expectedResponse = Enumerable.Range(0, 500).Select(i => i.ToString(CultureInfo.InvariantCulture)).ToList();
- using SemaphoreSlim enforcedConcurrentCallSemaphore = new(20);
- await this.RunWebSocketMultiPacketStreamingTestAsync(
- expectedResponse: expectedResponse,
- nbConcurrentCalls: 1,
- nbConcurrentEnumeration: 100,
- isPersistent: true,
- keepAliveWebSocketsDuration: 100,
- concurrentCallsTicksDelay: 0,
- enforcedConcurrentCallSemaphore: enforcedConcurrentCallSemaphore,
- maxExpectedNbClients: 20);
- }
-
- private async Task RunWebSocketMultiPacketStreamingTestAsync(
- string requestMessage = CompletionMultiText,
- List? expectedResponse = null,
- int nbConcurrentCalls = 1,
- int nbConcurrentEnumeration = 1,
- bool isPersistent = false,
- int requestProcessingDuration = 0,
- int segmentMessageDelay = 0,
- int keepAliveWebSocketsDuration = 100,
- int concurrentCallsTicksDelay = 0,
- SemaphoreSlim? enforcedConcurrentCallSemaphore = null,
- int maxExpectedNbClients = 0,
- int maxTestDuration = 0)
- {
- if (expectedResponse == null)
- {
- expectedResponse = new List { " John", ". I", "'m a", " writer" };
- }
-
- Func? webSocketFactory = null;
- // Counter to track the number of WebSocket clients created
- int clientCount = 0;
- var delayTimeSpan = new TimeSpan(concurrentCallsTicksDelay);
- if (isPersistent)
- {
- ClientWebSocket ExternalWebSocketFactory()
- {
- this._logger?.LogInformation(message: "Creating new client web socket");
- var toReturn = new ClientWebSocket();
- return toReturn;
- }
-
- if (maxExpectedNbClients > 0)
- {
- ClientWebSocket IncrementFactory()
- {
- var toReturn = ExternalWebSocketFactory();
- Interlocked.Increment(ref clientCount);
- return toReturn;
- }
-
- webSocketFactory = IncrementFactory;
- }
- else
- {
- webSocketFactory = ExternalWebSocketFactory;
- }
- }
-
- using var cleanupToken = new CancellationTokenSource();
-
- var sut = new OobaboogaTextCompletion(
- endpoint: new Uri("http://localhost/"),
- streamingPort: StreamingPort,
- httpClient: this._httpClient,
- webSocketsCleanUpCancellationToken: cleanupToken.Token,
- webSocketFactory: webSocketFactory,
- keepAliveWebSocketsDuration: keepAliveWebSocketsDuration,
- concurrentSemaphore: enforcedConcurrentCallSemaphore,
- logger: this._logger);
-
- await using var server = new OobaboogaWebSocketTestServer($"http://localhost:{StreamingPort}/", request => expectedResponse, logger: this._logger)
- {
- RequestProcessingDelay = TimeSpan.FromMilliseconds(requestProcessingDuration),
- SegmentMessageDelay = TimeSpan.FromMilliseconds(segmentMessageDelay)
- };
-
- var sw = Stopwatch.StartNew();
- var tasks = new List>>();
-
- for (int i = 0; i < nbConcurrentCalls; i++)
- {
- tasks.Add(Task.FromResult(sut.CompleteStreamAsync(requestMessage, new TextCompletionRequest()
- {
- Temperature = 0.01,
- MaxNewTokens = 7,
- TopP = 0.1,
- }, cancellationToken: cleanupToken.Token)));
- }
-
- var callEnumerationTasks = new List>>();
- var results = await Task.WhenAll(tasks);
-
- foreach (var completion in results)
- {
- callEnumerationTasks.AddRange(Enumerable.Range(0, nbConcurrentEnumeration).Select(_ => Task.Run(async () =>
- {
- var result = new List();
- await foreach (var chunk in completion)
- {
- result.Add(chunk);
- }
-
- return result;
- })));
-
- // Introduce a delay between creating each WebSocket client
- await Task.Delay(delayTimeSpan);
- }
-
- var allResults = await Task.WhenAll(callEnumerationTasks);
-
- var elapsed = sw.ElapsedMilliseconds;
- if (maxExpectedNbClients > 0)
- {
- Assert.InRange(clientCount, 1, maxExpectedNbClients);
- }
-
- // Validate all results
- foreach (var result in allResults)
- {
- Assert.Equal(expectedResponse.Count, result.Count);
- for (int i = 0; i < expectedResponse.Count; i++)
- {
- Assert.Equal(expectedResponse[i], result[i]);
- }
- }
-
- if (maxTestDuration > 0)
- {
- Assert.InRange(elapsed, 0, maxTestDuration);
- }
- }
-
- public void Dispose()
- {
- this._httpClient.Dispose();
- this._messageHandlerStub.Dispose();
- this._logger.Dispose();
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/WebSocketTestServer.cs b/dotnet/src/Connectors/Connectors.UnitTests/WebSocketTestServer.cs
deleted file mode 100644
index c833797f3219..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/WebSocketTestServer.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.WebSockets;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-
-namespace SemanticKernel.Connectors.UnitTests;
-
-internal class WebSocketTestServer : IDisposable
-{
- private readonly ILogger? _logger;
-
- private readonly HttpListener _httpListener;
- private readonly CancellationTokenSource _mainCancellationTokenSource;
- private readonly CancellationTokenSource _socketCancellationTokenSource;
- private bool _serverIsRunning;
-
- private readonly Func, List>> _arraySegmentHandler;
- private readonly ConcurrentDictionary> _requestContentQueues;
- private readonly ConcurrentBag _runningTasks = new();
-
- private readonly ConcurrentDictionary _clients = new();
-
- private readonly Task? _handleRequestTask = null;
-
- public TimeSpan RequestProcessingDelay { get; set; } = TimeSpan.Zero;
- public TimeSpan SegmentMessageDelay { get; set; } = TimeSpan.Zero;
-
- public ConcurrentDictionary RequestContents
- {
- get
- {
- return new ConcurrentDictionary(
- this._requestContentQueues
- .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToList().SelectMany(bytes => bytes).ToArray()));
- }
- }
-
- public WebSocketTestServer(string url, Func, List>> arraySegmentHandler, ILogger? logger = null)
- {
- this._logger = logger;
-
- this._arraySegmentHandler = arraySegmentHandler;
- this._requestContentQueues = new ConcurrentDictionary>();
-
- this._mainCancellationTokenSource = new();
- this._socketCancellationTokenSource = new();
-
- this._httpListener = new HttpListener();
- this._httpListener.Prefixes.Add(url);
- this._httpListener.Start();
- this._serverIsRunning = true;
-
- if (this._handleRequestTask is null || this._handleRequestTask.IsCompleted)
- {
- this._handleRequestTask = Task.Run((Func)this.HandleRequestsAsync, this._mainCancellationTokenSource.Token);
- }
- }
-
- private async Task HandleRequestsAsync()
- {
- while (!this._mainCancellationTokenSource.IsCancellationRequested)
- {
- var context = await this._httpListener.GetContextAsync().ConfigureAwait(false);
-
- if (this._serverIsRunning)
- {
- if (context.Request.IsWebSocketRequest)
- {
- var connectedClient = new ConnectedClient(Guid.NewGuid(), context);
- this._clients[connectedClient.Id] = connectedClient;
- try
- {
- var socketContext = await context.AcceptWebSocketAsync(subProtocol: null);
- connectedClient.SetSocket(socketContext.WebSocket);
- this._runningTasks.Add(this.HandleSingleWebSocketRequestAsync(connectedClient));
- }
- catch
- {
- // server error if upgrade from HTTP to WebSocket fails
- context.Response.StatusCode = 500;
- context.Response.StatusDescription = "WebSocket upgrade failed";
- context.Response.Close();
- throw;
- }
- }
- }
- else
- {
- // HTTP 409 Conflict (with server's current state)
- context.Response.StatusCode = 409;
- context.Response.StatusDescription = "Server is shutting down";
- context.Response.Close();
- return;
- }
- }
-
- await Task.WhenAll(this._runningTasks).ConfigureAwait(false);
- }
-
- private async Task HandleSingleWebSocketRequestAsync(ConnectedClient connectedClient)
- {
- var buffer = WebSocket.CreateServerBuffer(4096);
-
- Guid requestId = connectedClient.Id;
- this._requestContentQueues[requestId] = new ConcurrentQueue();
-
- try
- {
- while (!this._socketCancellationTokenSource.IsCancellationRequested && connectedClient.Socket != null && connectedClient.Socket.State != WebSocketState.Closed && connectedClient.Socket.State != WebSocketState.Aborted)
- {
- WebSocketReceiveResult result = await connectedClient.Socket.ReceiveAsync(buffer, this._socketCancellationTokenSource.Token).ConfigureAwait(false);
- if (!this._socketCancellationTokenSource.IsCancellationRequested && connectedClient.Socket.State != WebSocketState.Closed && connectedClient.Socket.State != WebSocketState.Aborted)
- {
- if (connectedClient.Socket.State == WebSocketState.CloseReceived && result.MessageType == WebSocketMessageType.Close)
- {
- await connectedClient.Socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Acknowledge Close frame", CancellationToken.None);
-
- break;
- }
-
- var receivedBytes = buffer.Slice(0, result.Count);
- this._requestContentQueues[requestId].Enqueue(receivedBytes.ToArray());
-
- if (result.EndOfMessage)
- {
- var responseSegments = this._arraySegmentHandler(receivedBytes);
-
- if (this.RequestProcessingDelay.Ticks > 0)
- {
- await Task.Delay(this.RequestProcessingDelay).ConfigureAwait(false);
- }
-
- foreach (var responseSegment in responseSegments)
- {
- if (connectedClient.Socket.State != WebSocketState.Open)
- {
- break;
- }
-
- if (this.SegmentMessageDelay.Ticks > 0)
- {
- await Task.Delay(this.SegmentMessageDelay).ConfigureAwait(false);
- }
-
- await connectedClient.Socket.SendAsync(responseSegment, WebSocketMessageType.Text, true, this._socketCancellationTokenSource.Token).ConfigureAwait(false);
- }
- }
- }
- }
-
- if (connectedClient.Socket?.State == WebSocketState.Open)
- {
- await connectedClient.Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing waiting for acknowledgement", CancellationToken.None).ConfigureAwait(false);
- }
- else if (connectedClient.Socket?.State == WebSocketState.CloseReceived)
- {
- await connectedClient.Socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Closing without waiting for acknowledgment", CancellationToken.None).ConfigureAwait(false);
- }
- }
- catch (OperationCanceledException exception)
- {
- this._logger?.LogTrace(message: "Closing server web socket before disposal was cancelled", exception: exception);
- }
- catch (WebSocketException exception)
- {
- this._logger?.LogTrace(message: "Closing server web socket before disposal raised web socket exception", exception: exception);
- }
- finally
- {
- if (connectedClient.Socket?.State != WebSocketState.Closed)
- {
- connectedClient.Socket?.Abort();
- }
-
- connectedClient.Socket?.Dispose();
-
- // Remove client from dictionary when done
- this._clients.TryRemove(requestId, out _);
- }
- }
-
- private async Task CloseAllSocketsAsync()
- {
- // Close all active sockets before disposing
- foreach (var client in this._clients.Values)
- {
- if (client.Socket?.State == WebSocketState.Open)
- {
- await client.Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", this._mainCancellationTokenSource.Token);
- }
- }
- }
-
- public async ValueTask DisposeAsync()
- {
- try
- {
- this._serverIsRunning = false;
- await this.CloseAllSocketsAsync(); // Close all sockets before finishing the tasks
- await Task.WhenAll(this._runningTasks).ConfigureAwait(false);
- this._socketCancellationTokenSource.Cancel();
- this._mainCancellationTokenSource.Cancel();
- }
- catch (OperationCanceledException exception)
- {
- this._logger?.LogTrace(message: "\"Disposing web socket test server raised operation cancel exception", exception: exception);
- }
- finally
- {
- this._httpListener.Stop();
- this._httpListener.Close();
- this._socketCancellationTokenSource.Dispose();
- this._mainCancellationTokenSource.Dispose();
- }
- }
-
-#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
- public void Dispose()
- {
- this.DisposeAsync().AsTask().GetAwaiter().GetResult();
- }
-}
diff --git a/dotnet/src/Connectors/Connectors.UnitTests/XunitLogger.cs b/dotnet/src/Connectors/Connectors.UnitTests/XunitLogger.cs
deleted file mode 100644
index 6a6ad5c22bc6..000000000000
--- a/dotnet/src/Connectors/Connectors.UnitTests/XunitLogger.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using Microsoft.Extensions.Logging;
-using Xunit.Abstractions;
-
-namespace SemanticKernel.Connectors.UnitTests;
-
-///
-/// A logger that writes to the Xunit test output
-///
-internal sealed class XunitLogger : ILogger, IDisposable
-{
- private readonly ITestOutputHelper _output;
-
- public XunitLogger(ITestOutputHelper output)
- {
- this._output = output;
- }
-
- ///
- public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
- {
- this._output.WriteLine(state?.ToString());
- }
-
- ///
- public bool IsEnabled(LogLevel logLevel) => true;
-
- ///
- public IDisposable BeginScope(TState state)
- => this;
-
- ///
- public void Dispose()
- {
- // This class is marked as disposable to support the BeginScope method.
- // However, there is no need to dispose anything.
- }
-}
diff --git a/dotnet/src/IntegrationTests/Connectors/Oobabooga/OobaboogaTextCompletionTests.cs b/dotnet/src/IntegrationTests/Connectors/Oobabooga/OobaboogaTextCompletionTests.cs
deleted file mode 100644
index b094f4e449bd..000000000000
--- a/dotnet/src/IntegrationTests/Connectors/Oobabooga/OobaboogaTextCompletionTests.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-
-using System;
-using System.Collections.Generic;
-using System.Net.WebSockets;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Configuration;
-using Microsoft.SemanticKernel.AI.TextCompletion;
-using Microsoft.SemanticKernel.Connectors.AI.Oobabooga.TextCompletion;
-using Xunit;
-
-namespace SemanticKernel.IntegrationTests.Connectors.Oobabooga;
-
-///
-/// Integration tests for .
-///
-[Obsolete("This functionality is available as part of new NuGet package: https://www.nuget.org/packages/MyIA.SemanticKernel.Connectors.AI.Oobabooga/. This will be removed in a future release.")]
-public sealed class OobaboogaTextCompletionTests : IDisposable
-{
- private const string Endpoint = "http://localhost";
- private const int BlockingPort = 5000;
- private const int StreamingPort = 5005;
-
- private readonly IConfigurationRoot _configuration;
- private readonly List _webSockets = new();
- private readonly Func _webSocketFactory;
-
- public OobaboogaTextCompletionTests()
- {
- // Load configuration
- this._configuration = new ConfigurationBuilder()
- .AddJsonFile(path: "testsettings.json", optional: false, reloadOnChange: true)
- .AddJsonFile(path: "testsettings.development.json", optional: true, reloadOnChange: true)
- .AddEnvironmentVariables()
- .Build();
- this._webSocketFactory = () =>
- {
- var toReturn = new ClientWebSocket();
- this._webSockets.Add(toReturn);
- return toReturn;
- };
- }
-
- private const string Input = " My name is";
-
- [Fact(Skip = "This test is for manual verification.")]
- public async Task OobaboogaLocalTextCompletionAsync()
- {
- var oobaboogaLocal = new OobaboogaTextCompletion(
- endpoint: new Uri(Endpoint),
- blockingPort: BlockingPort);
-
- // Act
- var localResponse = await oobaboogaLocal.CompleteAsync(Input, requestSettings: new TextCompletionRequest()
- {
- Temperature = 0.01,
- MaxNewTokens = 7,
- TopP = 0.1,
- });
-
- AssertAcceptableResponse(localResponse);
- }
-
- [Fact(Skip = "This test is for manual verification.")]
- public async Task OobaboogaLocalTextCompletionStreamingAsync()
- {
- var oobaboogaLocal = new OobaboogaTextCompletion(
- endpoint: new Uri(Endpoint),
- streamingPort: StreamingPort,
- webSocketFactory: this._webSocketFactory);
-
- // Act
- var localResponse = oobaboogaLocal.CompleteStreamAsync(Input, requestSettings: new TextCompletionRequest()
- {
- Temperature = 0.01,
- MaxNewTokens = 7,
- TopP = 0.1,
- });
-
- StringBuilder stringBuilder = new();
- await foreach (var result in localResponse)
- {
- stringBuilder.Append(result);
- }
-
- var resultsMerged = stringBuilder.ToString();
- AssertAcceptableResponse(resultsMerged);
- }
-
- private static void AssertAcceptableResponse(string localResponse)
- {
- // Assert
- Assert.NotNull(localResponse);
- // Depends on the target LLM obviously, but most LLMs should propose an arbitrary surname preceded by a white space, including the start prompt or not
- // ie " My name is" => " John (...)" or " My name is" => " My name is John (...)".
- // Here are a couple LLMs that were tested successfully: gpt2, aisquared_dlite-v1-355m, bigscience_bloomz-560m, eachadea_vicuna-7b-1.1, TheBloke_WizardLM-30B-GPTQ etc.
- // A few will return an empty string, but well those shouldn't be used for integration tests.
- var expectedRegex = new Regex(@"\s\w+.*");
- Assert.Matches(expectedRegex, localResponse);
- }
-
- public void Dispose()
- {
- foreach (ClientWebSocket clientWebSocket in this._webSockets)
- {
- clientWebSocket.Dispose();
- }
- }
-}
diff --git a/dotnet/src/IntegrationTests/IntegrationTests.csproj b/dotnet/src/IntegrationTests/IntegrationTests.csproj
index cce2ae451319..7b2e9a85a212 100644
--- a/dotnet/src/IntegrationTests/IntegrationTests.csproj
+++ b/dotnet/src/IntegrationTests/IntegrationTests.csproj
@@ -31,7 +31,6 @@
-