mirror of
				https://github.com/MindWorkAI/AI-Studio.git
				synced 2025-11-04 06:40:20 +00:00 
			
		
		
		
	Added a ERI ((E)xternal (R)etrieval (I)nterface) client for communication with any ERI server.
This commit is contained in:
		
							parent
							
								
									abaa4fa7b7
								
							
						
					
					
						commit
						da76be282b
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,10 +0,0 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <PropertyGroup>
 | 
					 | 
				
			||||||
        <TargetFramework>net8.0</TargetFramework>
 | 
					 | 
				
			||||||
        <LangVersion>latest</LangVersion>
 | 
					 | 
				
			||||||
        <ImplicitUsings>enable</ImplicitUsings>
 | 
					 | 
				
			||||||
        <Nullable>enable</Nullable>
 | 
					 | 
				
			||||||
    </PropertyGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</Project>
 | 
					 | 
				
			||||||
@ -2,10 +2,6 @@
 | 
				
			|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
					Microsoft Visual Studio Solution File, Format Version 12.00
 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindWork AI Studio", "MindWork AI Studio\MindWork AI Studio.csproj", "{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}"
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindWork AI Studio", "MindWork AI Studio\MindWork AI Studio.csproj", "{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}"
 | 
				
			||||||
EndProject
 | 
					EndProject
 | 
				
			||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ERIClients", "ERIClients", "{5C2AF789-287B-4FCB-B675-7273D8CD4579}"
 | 
					 | 
				
			||||||
EndProject
 | 
					 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ERIClientV1", "ERIClientV1\ERIClientV1.csproj", "{9E35A273-0FA6-4BD5-8880-A1DDAC106926}"
 | 
					 | 
				
			||||||
EndProject
 | 
					 | 
				
			||||||
Global
 | 
					Global
 | 
				
			||||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
		Debug|Any CPU = Debug|Any CPU
 | 
							Debug|Any CPU = Debug|Any CPU
 | 
				
			||||||
@ -16,12 +12,7 @@ Global
 | 
				
			|||||||
		{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
							{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
		{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
							{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
		{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
							{059FDFCC-7D0B-474E-9F20-B9C437DF1CDD}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
		{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{9E35A273-0FA6-4BD5-8880-A1DDAC106926}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
	EndGlobalSection
 | 
						EndGlobalSection
 | 
				
			||||||
	GlobalSection(NestedProjects) = preSolution
 | 
						GlobalSection(NestedProjects) = preSolution
 | 
				
			||||||
		{9E35A273-0FA6-4BD5-8880-A1DDAC106926} = {5C2AF789-287B-4FCB-B675-7273D8CD4579}
 | 
					 | 
				
			||||||
	EndGlobalSection
 | 
						EndGlobalSection
 | 
				
			||||||
EndGlobal
 | 
					EndGlobal
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,7 @@
 | 
				
			|||||||
using AIStudio.Dialogs;
 | 
					using AIStudio.Dialogs;
 | 
				
			||||||
using AIStudio.Settings;
 | 
					using AIStudio.Settings;
 | 
				
			||||||
using AIStudio.Settings.DataModel;
 | 
					using AIStudio.Settings.DataModel;
 | 
				
			||||||
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
using ERI_Client.V1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Microsoft.AspNetCore.Components;
 | 
					using Microsoft.AspNetCore.Components;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -53,10 +53,6 @@
 | 
				
			|||||||
      <PackageReference Include="ReverseMarkdown" Version="4.6.0" />
 | 
					      <PackageReference Include="ReverseMarkdown" Version="4.6.0" />
 | 
				
			||||||
    </ItemGroup>
 | 
					    </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <ItemGroup>
 | 
					 | 
				
			||||||
      <ProjectReference Include="..\ERIClientV1\ERIClientV1.csproj" />
 | 
					 | 
				
			||||||
    </ItemGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Read the meta data file -->
 | 
					    <!-- Read the meta data file -->
 | 
				
			||||||
    <Target Name="ReadMetaData" BeforeTargets="BeforeBuild">
 | 
					    <Target Name="ReadMetaData" BeforeTargets="BeforeBuild">
 | 
				
			||||||
        <Error Text="The ../../metadata.txt file was not found!" Condition="!Exists('../../metadata.txt')" />
 | 
					        <Error Text="The ../../metadata.txt file was not found!" Condition="!Exists('../../metadata.txt')" />
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,7 @@
 | 
				
			|||||||
using ERI_Client.V1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReSharper disable InconsistentNaming
 | 
					// ReSharper disable InconsistentNaming
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AIStudio.Settings.DataModel;
 | 
					namespace AIStudio.Settings.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// <summary>
 | 
					/// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
using ERI_Client.V1;
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AIStudio.Settings;
 | 
					namespace AIStudio.Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
using ERI_Client.V1;
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AIStudio.Tools;
 | 
					namespace AIStudio.Tools;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										19
									
								
								app/MindWork AI Studio/Tools/ERIClient/APIResponse.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/MindWork AI Studio/Tools/ERIClient/APIResponse.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public sealed class APIResponse<T>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Was the API call successful?
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public bool Successful { get; set; }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// When the API call was not successful, this will contain the error message.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public string Message { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The data returned by the API call.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public T? Data { get; set; }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// An authentication field.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum AuthField
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NONE,
 | 
				
			||||||
 | 
					    USERNAME,
 | 
				
			||||||
 | 
					    PASSWORD,
 | 
				
			||||||
 | 
					    TOKEN,
 | 
				
			||||||
 | 
					    KERBEROS_TICKET,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The mapping between an AuthField and the field name in the authentication request.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="AuthField">The AuthField that is mapped to the field name.</param>
 | 
				
			||||||
 | 
					/// <param name="FieldName">The field name in the authentication request.</param>
 | 
				
			||||||
 | 
					public record AuthFieldMapping(AuthField AuthField, string FieldName);
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum AuthMethod
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NONE,
 | 
				
			||||||
 | 
					    KERBEROS,
 | 
				
			||||||
 | 
					    USERNAME_PASSWORD,
 | 
				
			||||||
 | 
					    TOKEN,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The response to an authentication request.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="Success">True, when the authentication was successful.</param>
 | 
				
			||||||
 | 
					/// <param name="Token">The token to use for further requests.</param>
 | 
				
			||||||
 | 
					/// <param name="Message">When the authentication was not successful, this contains the reason.</param>
 | 
				
			||||||
 | 
					public readonly record struct AuthResponse(bool Success, string? Token, string? Message);
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Describes one authentication scheme for this data source. 
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="AuthMethod">The method used for authentication, e.g., "API Key," "Username/Password," etc.</param>
 | 
				
			||||||
 | 
					/// <param name="AuthFieldMappings">A list of field mappings for the authentication method. The client must know,
 | 
				
			||||||
 | 
					/// e.g., how the password field is named in the request.</param> 
 | 
				
			||||||
 | 
					public readonly record struct AuthScheme(AuthMethod AuthMethod, List<AuthFieldMapping> AuthFieldMappings);
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A chat thread, which is a list of content blocks.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="ContentBlocks">The content blocks in this chat thread.</param>
 | 
				
			||||||
 | 
					public readonly record struct ChatThread(List<ContentBlock> ContentBlocks);
 | 
				
			||||||
@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// A block of content of a chat thread.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// Images and other media are base64 encoded.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					/// <param name="Content">The content of the block. Remember that images and other media are base64 encoded.</param>
 | 
				
			||||||
 | 
					/// <param name="Role">The role of the content in the chat thread.</param>
 | 
				
			||||||
 | 
					/// <param name="Type">The type of the content, e.g., text, image, video, etc.</param>
 | 
				
			||||||
 | 
					public readonly record struct ContentBlock(string Content, Role Role, ContentType Type);
 | 
				
			||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The type of content.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum ContentType
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NONE,
 | 
				
			||||||
 | 
					    UNKNOWN,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    TEXT,
 | 
				
			||||||
 | 
					    IMAGE,
 | 
				
			||||||
 | 
					    VIDEO,
 | 
				
			||||||
 | 
					    AUDIO,
 | 
				
			||||||
 | 
					    SPEECH,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								app/MindWork AI Studio/Tools/ERIClient/DataModel/Context.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/MindWork AI Studio/Tools/ERIClient/DataModel/Context.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Matching context returned by the data source as a result of a retrieval request.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="Name">The name of the source, e.g., a document name, database name,
 | 
				
			||||||
 | 
					/// collection name, etc.</param>
 | 
				
			||||||
 | 
					/// <param name="Category">What are the contents of the source? For example, is it a
 | 
				
			||||||
 | 
					/// dictionary, a book chapter, business concept, a paper, etc.</param>
 | 
				
			||||||
 | 
					/// <param name="Path">The path to the content, e.g., a URL, a file path, a path in a
 | 
				
			||||||
 | 
					/// graph database, etc.</param>
 | 
				
			||||||
 | 
					/// <param name="Type">The type of the content, e.g., text, image, video, audio, speech, etc.</param>
 | 
				
			||||||
 | 
					/// <param name="MatchedContent">The content that matched the user prompt. For text, you
 | 
				
			||||||
 | 
					/// return the matched text and, e.g., three words before and after it.</param>
 | 
				
			||||||
 | 
					/// <param name="SurroundingContent">The surrounding content of the matched content.
 | 
				
			||||||
 | 
					/// For text, you may return, e.g., one sentence or paragraph before and after
 | 
				
			||||||
 | 
					/// the matched content.</param>
 | 
				
			||||||
 | 
					/// <param name="Links">Links to related content, e.g., links to Wikipedia articles,
 | 
				
			||||||
 | 
					/// links to sources, etc.</param>
 | 
				
			||||||
 | 
					public readonly record struct Context(
 | 
				
			||||||
 | 
					    string Name,
 | 
				
			||||||
 | 
					    string Category,
 | 
				
			||||||
 | 
					    string? Path,
 | 
				
			||||||
 | 
					    ContentType Type,
 | 
				
			||||||
 | 
					    string MatchedContent,
 | 
				
			||||||
 | 
					    string[] SurroundingContent,
 | 
				
			||||||
 | 
					    string[] Links);
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about the data source.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="Name">The name of the data source, e.g., "Internal Organization Documents."</param>
 | 
				
			||||||
 | 
					/// <param name="Description">A short description of the data source. What kind of data does it contain?
 | 
				
			||||||
 | 
					/// What is the data source used for?</param>
 | 
				
			||||||
 | 
					public readonly record struct DataSourceInfo(string Name, string Description);
 | 
				
			||||||
@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Represents information about the used embedding for this data source. The purpose of this information is to give the
 | 
				
			||||||
 | 
					/// interested user an idea of what kind of embedding is used and what it does.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="EmbeddingType">What kind of embedding is used. For example, "Transformer Embedding," "Contextual Word
 | 
				
			||||||
 | 
					/// Embedding," "Graph Embedding," etc.</param>
 | 
				
			||||||
 | 
					/// <param name="EmbeddingName">Name the embedding used. This can be a library, a framework, or the name of the used
 | 
				
			||||||
 | 
					/// algorithm.</param>
 | 
				
			||||||
 | 
					/// <param name="Description">A short description of the embedding. Describe what the embedding is doing.</param>
 | 
				
			||||||
 | 
					/// <param name="UsedWhen">Describe when the embedding is used. For example, when the user prompt contains certain
 | 
				
			||||||
 | 
					/// keywords, or anytime?</param>
 | 
				
			||||||
 | 
					/// <param name="Link">A link to the embedding's documentation or the source code. Might be null.</param>
 | 
				
			||||||
 | 
					public readonly record struct EmbeddingInfo(
 | 
				
			||||||
 | 
					    string EmbeddingType,
 | 
				
			||||||
 | 
					    string EmbeddingName,
 | 
				
			||||||
 | 
					    string Description,
 | 
				
			||||||
 | 
					    string UsedWhen,
 | 
				
			||||||
 | 
					    string? Link);
 | 
				
			||||||
@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Known types of providers that can process data.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum ProviderType
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The related data is not allowed to be sent to any provider.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    NONE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The related data can be sent to any provider.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    ANY,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// The related data can be sent to a provider that is hosted by the same organization, either on-premises or locally.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    SELF_HOSTED,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Information about a retrieval process, which this data source implements.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="Id">A unique identifier for the retrieval process. This can be a GUID, a unique name, or an increasing integer.</param>
 | 
				
			||||||
 | 
					/// <param name="Name">The name of the retrieval process, e.g., "Keyword-Based Wikipedia Article Retrieval".</param>
 | 
				
			||||||
 | 
					/// <param name="Description">A short description of the retrieval process. What kind of retrieval process is it?</param>
 | 
				
			||||||
 | 
					/// <param name="Link">A link to the retrieval process's documentation, paper, Wikipedia article, or the source code. Might be null.</param>
 | 
				
			||||||
 | 
					/// <param name="ParametersDescription">A dictionary that describes the parameters of the retrieval process. The key is the parameter name,
 | 
				
			||||||
 | 
					/// and the value is a description of the parameter. Although each parameter will be sent as a string, the description should indicate the
 | 
				
			||||||
 | 
					/// expected type and range, e.g., 0.0 to 1.0 for a float parameter.</param>
 | 
				
			||||||
 | 
					/// <param name="Embeddings">A list of embeddings used in this retrieval process. It might be empty in case no embedding is used.</param>
 | 
				
			||||||
 | 
					public readonly record struct RetrievalInfo(
 | 
				
			||||||
 | 
					    string Id,
 | 
				
			||||||
 | 
					    string Name,
 | 
				
			||||||
 | 
					    string Description,
 | 
				
			||||||
 | 
					    string? Link,
 | 
				
			||||||
 | 
					    Dictionary<string, string>? ParametersDescription,
 | 
				
			||||||
 | 
					    List<EmbeddingInfo> Embeddings);
 | 
				
			||||||
@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// The retrieval request sent by AI Studio.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <remarks>
 | 
				
			||||||
 | 
					/// Images and other media are base64 encoded.
 | 
				
			||||||
 | 
					/// </remarks>
 | 
				
			||||||
 | 
					/// <param name="LatestUserPrompt">The latest user prompt that AI Studio received.</param>
 | 
				
			||||||
 | 
					/// <param name="LatestUserPromptType">The type of the latest user prompt, e.g., text, image, etc.</param>
 | 
				
			||||||
 | 
					/// <param name="Thread">The chat thread that the user is currently in.</param>
 | 
				
			||||||
 | 
					/// <param name="RetrievalProcessId">Optional. The ID of the retrieval process that the data source should use.
 | 
				
			||||||
 | 
					/// When null, the data source chooses an appropriate retrieval process. Selecting a retrieval process is optional
 | 
				
			||||||
 | 
					/// for AI Studio users. Most users do not specify a retrieval process.</param>
 | 
				
			||||||
 | 
					/// <param name="Parameters">A dictionary of parameters that the data source should use for the retrieval process.
 | 
				
			||||||
 | 
					/// Although each parameter will be sent as a string, the retrieval process specifies the expected type and range.</param>
 | 
				
			||||||
 | 
					/// <param name="MaxMatches">The maximum number of matches that the data source should return. AI Studio uses
 | 
				
			||||||
 | 
					/// any value below 1 to indicate that the data source should return as many matches as appropriate.</param>
 | 
				
			||||||
 | 
					public readonly record struct RetrievalRequest(
 | 
				
			||||||
 | 
					    string LatestUserPrompt,
 | 
				
			||||||
 | 
					    ContentType LatestUserPromptType,
 | 
				
			||||||
 | 
					    ChatThread Thread,
 | 
				
			||||||
 | 
					    string? RetrievalProcessId,
 | 
				
			||||||
 | 
					    Dictionary<string, string>? Parameters,
 | 
				
			||||||
 | 
					    int MaxMatches);
 | 
				
			||||||
							
								
								
									
										15
									
								
								app/MindWork AI Studio/Tools/ERIClient/DataModel/Role.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/MindWork AI Studio/Tools/ERIClient/DataModel/Role.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Possible roles of any chat thread.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					public enum Role
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    NONE,
 | 
				
			||||||
 | 
					    UNKNOW,
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    SYSTEM,
 | 
				
			||||||
 | 
					    USER,
 | 
				
			||||||
 | 
					    AI,
 | 
				
			||||||
 | 
					    AGENT,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					namespace AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// <summary>
 | 
				
			||||||
 | 
					/// Represents the security requirements for this data source.
 | 
				
			||||||
 | 
					/// </summary>
 | 
				
			||||||
 | 
					/// <param name="AllowedProviderType">Which provider types are allowed to process the data?</param>
 | 
				
			||||||
 | 
					public readonly record struct SecurityRequirements(ProviderType AllowedProviderType);
 | 
				
			||||||
							
								
								
									
										36
									
								
								app/MindWork AI Studio/Tools/ERIClient/ERIClientBase.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/MindWork AI Studio/Tools/ERIClient/ERIClientBase.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					using System.Text.Json;
 | 
				
			||||||
 | 
					using System.Text.Json.Serialization;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace AIStudio.Tools.ERIClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class ERIClientBase(string baseAddress) : IDisposable
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected static readonly JsonSerializerOptions JSON_OPTIONS = new()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        WriteIndented = true,
 | 
				
			||||||
 | 
					        AllowTrailingCommas = true,
 | 
				
			||||||
 | 
					        PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
 | 
				
			||||||
 | 
					        DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
 | 
				
			||||||
 | 
					        PropertyNameCaseInsensitive = true,
 | 
				
			||||||
 | 
					        Converters =
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseUpper),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    protected readonly HttpClient httpClient = new()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        BaseAddress = new Uri(baseAddress),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    protected string securityToken = string.Empty;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    #region Implementation of IDisposable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void Dispose()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        this.httpClient.Dispose();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #endregion
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								app/MindWork AI Studio/Tools/ERIClient/ERIClientFactory.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/MindWork AI Studio/Tools/ERIClient/ERIClientFactory.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					using AIStudio.Assistants.ERI;
 | 
				
			||||||
 | 
					using AIStudio.Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace AIStudio.Tools.ERIClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public static class ERIClientFactory
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static IERIClient? Get(ERIVersion version, IERIDataSource dataSource) => version switch
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ERIVersion.V1 => new ERIClientV1($"{dataSource.Hostname}:{dataSource.Port}"),
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        _ => null
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										344
									
								
								app/MindWork AI Studio/Tools/ERIClient/ERIClientV1.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										344
									
								
								app/MindWork AI Studio/Tools/ERIClient/ERIClientV1.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,344 @@
 | 
				
			|||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Text.Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using AIStudio.Settings;
 | 
				
			||||||
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace AIStudio.Tools.ERIClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIClient
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    #region Implementation of IERIClient
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<List<AuthScheme>>> GetAuthMethodsAsync(CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var response = await this.httpClient.GetAsync("/auth/methods", cancellationToken);
 | 
				
			||||||
 | 
					        if(!response.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = $"Failed to retrieve the authentication methods: there was an issue communicating with the ERI server. Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var authMethods = await response.Content.ReadFromJsonAsync<List<AuthScheme>>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					        if(authMethods is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = "Failed to retrieve the authentication methods: the ERI server did not return a valid response."
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Successful = true,
 | 
				
			||||||
 | 
					            Data = authMethods
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<AuthResponse>> AuthenticateAsync(IERIDataSource dataSource, RustService rustService, CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var authMethod = dataSource.AuthMethod;
 | 
				
			||||||
 | 
					        var username = dataSource.Username;
 | 
				
			||||||
 | 
					        switch (dataSource.AuthMethod)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            case AuthMethod.NONE:
 | 
				
			||||||
 | 
					                using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    using var noneAuthResponse = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					                    if(!noneAuthResponse.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return new()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Successful = false,
 | 
				
			||||||
 | 
					                            Message = $"Failed to authenticate with the ERI server. Code: {noneAuthResponse.StatusCode}, Reason: {noneAuthResponse.ReasonPhrase}"
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    var noneAuthResult = await noneAuthResponse.Content.ReadFromJsonAsync<AuthResponse>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					                    if(noneAuthResult == default)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return new()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Successful = false,
 | 
				
			||||||
 | 
					                            Message = "Failed to authenticate with the ERI server: the response was invalid."
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    this.securityToken = noneAuthResult.Token ?? string.Empty;
 | 
				
			||||||
 | 
					                    return new()
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Successful = true,
 | 
				
			||||||
 | 
					                        Data = noneAuthResult
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            case AuthMethod.USERNAME_PASSWORD:
 | 
				
			||||||
 | 
					                var passwordResponse = await rustService.GetSecret(dataSource);
 | 
				
			||||||
 | 
					                if (!passwordResponse.Success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return new()
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Successful = false,
 | 
				
			||||||
 | 
					                        Message = "Failed to retrieve the password."
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var password = await passwordResponse.Secret.Decrypt(Program.ENCRYPTION);
 | 
				
			||||||
 | 
					                using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // We must send both values inside the header. The username field is named 'user'.
 | 
				
			||||||
 | 
					                    // The password field is named 'password'.
 | 
				
			||||||
 | 
					                    request.Headers.Add("user", username);
 | 
				
			||||||
 | 
					                    request.Headers.Add("password", password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    using var usernamePasswordAuthResponse = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					                    if(!usernamePasswordAuthResponse.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return new()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Successful = false,
 | 
				
			||||||
 | 
					                            Message = $"Failed to authenticate with the ERI server. Code: {usernamePasswordAuthResponse.StatusCode}, Reason: {usernamePasswordAuthResponse.ReasonPhrase}"
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    var usernamePasswordAuthResult = await usernamePasswordAuthResponse.Content.ReadFromJsonAsync<AuthResponse>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					                    if(usernamePasswordAuthResult == default)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return new()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Successful = false,
 | 
				
			||||||
 | 
					                            Message = "Failed to authenticate with the server: the response was invalid."
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    this.securityToken = usernamePasswordAuthResult.Token ?? string.Empty;
 | 
				
			||||||
 | 
					                    return new()
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Successful = true,
 | 
				
			||||||
 | 
					                        Data = usernamePasswordAuthResult
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            case AuthMethod.TOKEN:
 | 
				
			||||||
 | 
					                var tokenResponse = await rustService.GetSecret(dataSource);
 | 
				
			||||||
 | 
					                if (!tokenResponse.Success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return new()
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Successful = false,
 | 
				
			||||||
 | 
					                        Message = "Failed to retrieve the access token."
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var token = await tokenResponse.Secret.Decrypt(Program.ENCRYPTION);
 | 
				
			||||||
 | 
					                using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    request.Headers.Add("Authorization", $"Bearer {token}");
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    using var tokenAuthResponse = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					                    if(!tokenAuthResponse.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return new()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Successful = false,
 | 
				
			||||||
 | 
					                            Message = $"Failed to authenticate with the ERI server. Code: {tokenAuthResponse.StatusCode}, Reason: {tokenAuthResponse.ReasonPhrase}"
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    var tokenAuthResult = await tokenAuthResponse.Content.ReadFromJsonAsync<AuthResponse>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					                    if(tokenAuthResult == default)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        return new()
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            Successful = false,
 | 
				
			||||||
 | 
					                            Message = "Failed to authenticate with the ERI server: the response was invalid."
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    this.securityToken = tokenAuthResult.Token ?? string.Empty;
 | 
				
			||||||
 | 
					                    return new()
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        Successful = true,
 | 
				
			||||||
 | 
					                        Data = tokenAuthResult
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                this.securityToken = string.Empty;
 | 
				
			||||||
 | 
					                return new()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Successful = false,
 | 
				
			||||||
 | 
					                    Message = "The authentication method is not supported yet."
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<DataSourceInfo>> GetDataSourceInfoAsync(CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var request = new HttpRequestMessage(HttpMethod.Get, "/dataSource");
 | 
				
			||||||
 | 
					        request.Headers.Add("token", this.securityToken);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        using var response = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					        if(!response.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = $"Failed to retrieve the data source information: there was an issue communicating with the ERI server. Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        var dataSourceInfo = await response.Content.ReadFromJsonAsync<DataSourceInfo>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					        if(dataSourceInfo == default)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = "Failed to retrieve the data source information: the ERI server did not return a valid response."
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return new()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Successful = true,
 | 
				
			||||||
 | 
					            Data = dataSourceInfo
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<List<EmbeddingInfo>>> GetEmbeddingInfoAsync(CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var request = new HttpRequestMessage(HttpMethod.Get, "/embedding/info");
 | 
				
			||||||
 | 
					        request.Headers.Add("token", this.securityToken);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        using var response = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					        if(!response.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = $"Failed to retrieve the embedding information: there was an issue communicating with the ERI server. Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        var embeddingInfo = await response.Content.ReadFromJsonAsync<List<EmbeddingInfo>>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					        if(embeddingInfo is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = "Failed to retrieve the embedding information: the ERI server did not return a valid response."
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return new()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Successful = true,
 | 
				
			||||||
 | 
					            Data = embeddingInfo
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<List<RetrievalInfo>>> GetRetrievalInfoAsync(CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var request = new HttpRequestMessage(HttpMethod.Get, "/retrieval/info");
 | 
				
			||||||
 | 
					        request.Headers.Add("token", this.securityToken);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        using var response = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					        if(!response.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = $"Failed to retrieve the retrieval information: there was an issue communicating with the ERI server. Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        var retrievalInfo = await response.Content.ReadFromJsonAsync<List<RetrievalInfo>>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					        if(retrievalInfo is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = "Failed to retrieve the retrieval information: the ERI server did not return a valid response."
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return new()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Successful = true,
 | 
				
			||||||
 | 
					            Data = retrievalInfo
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<List<Context>>> ExecuteRetrievalAsync(RetrievalRequest request, CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/retrieval");
 | 
				
			||||||
 | 
					        requestMessage.Headers.Add("token", this.securityToken);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        using var content = new StringContent(JsonSerializer.Serialize(request, JSON_OPTIONS), Encoding.UTF8, "application/json");
 | 
				
			||||||
 | 
					        requestMessage.Content = content;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        using var response = await this.httpClient.SendAsync(requestMessage, cancellationToken);
 | 
				
			||||||
 | 
					        if(!response.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = $"Failed to execute the retrieval request: there was an issue communicating with the ERI server. Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        var contexts = await response.Content.ReadFromJsonAsync<List<Context>>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					        if(contexts is null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = "Failed to execute the retrieval request: the ERI server did not return a valid response."
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return new()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Successful = true,
 | 
				
			||||||
 | 
					            Data = contexts
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public async Task<APIResponse<SecurityRequirements>> GetSecurityRequirementsAsync(CancellationToken cancellationToken = default)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        using var request = new HttpRequestMessage(HttpMethod.Get, "/security/requirements");
 | 
				
			||||||
 | 
					        request.Headers.Add("token", this.securityToken);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        using var response = await this.httpClient.SendAsync(request, cancellationToken);
 | 
				
			||||||
 | 
					        if(!response.IsSuccessStatusCode)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = $"Failed to retrieve the security requirements: there was an issue communicating with the ERI server. Code: {response.StatusCode}, Reason: {response.ReasonPhrase}"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        var securityRequirements = await response.Content.ReadFromJsonAsync<SecurityRequirements>(JSON_OPTIONS, cancellationToken);
 | 
				
			||||||
 | 
					        if(securityRequirements == default)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Successful = false,
 | 
				
			||||||
 | 
					                Message = "Failed to retrieve the security requirements: the ERI server did not return a valid response."
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return new()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Successful = true,
 | 
				
			||||||
 | 
					            Data = securityRequirements
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #endregion
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								app/MindWork AI Studio/Tools/ERIClient/IERIClient.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								app/MindWork AI Studio/Tools/ERIClient/IERIClient.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					using AIStudio.Settings;
 | 
				
			||||||
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace AIStudio.Tools.ERIClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface IERIClient : IDisposable
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Retrieves the available authentication methods from the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <remarks>
 | 
				
			||||||
 | 
					    /// No authentication is required to retrieve the available authentication methods.
 | 
				
			||||||
 | 
					    /// </remarks>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>The available authentication methods.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<List<AuthScheme>>> GetAuthMethodsAsync(CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Authenticate the user to the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="dataSource">The data source to use.</param>
 | 
				
			||||||
 | 
					    /// <param name="rustService">The Rust service.</param>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>The authentication response.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<AuthResponse>> AuthenticateAsync(IERIDataSource dataSource, RustService rustService, CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Retrieves the data source information from the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>The data source information.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<DataSourceInfo>> GetDataSourceInfoAsync(CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Retrieves the embedding information from the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>A list of embedding information.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<List<EmbeddingInfo>>> GetEmbeddingInfoAsync(CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Retrieves the retrieval information from the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>A list of retrieval information.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<List<RetrievalInfo>>> GetRetrievalInfoAsync(CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Executes a retrieval request on the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="request">The retrieval request.</param>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>The retrieved contexts to use for augmentation and generation.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<List<Context>>> ExecuteRetrievalAsync(RetrievalRequest request, CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Retrieves the security requirements from the ERI server.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="cancellationToken">The cancellation token.</param>
 | 
				
			||||||
 | 
					    /// <returns>The security requirements.</returns>
 | 
				
			||||||
 | 
					    public Task<APIResponse<SecurityRequirements>> GetSecurityRequirementsAsync(CancellationToken cancellationToken = default);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
using ERI_Client.V1;
 | 
					using AIStudio.Tools.ERIClient.DataModel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace AIStudio.Tools.Validation;
 | 
					namespace AIStudio.Tools.Validation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
# v0.9.28, build 203 (2025-0x-xx xx:xx UTC)
 | 
					# v0.9.28, build 203 (2025-0x-xx xx:xx UTC)
 | 
				
			||||||
- Added an information view to all data sources to the data source configuration page. The data source configuration is a preview feature behind the RAG feature flag.
 | 
					- Added an information view to all data sources to the data source configuration page. The data source configuration is a preview feature behind the RAG feature flag.
 | 
				
			||||||
 | 
					- Added a ERI ((E)xternal (R)etrieval (I)nterface) client for communication with any ERI server.
 | 
				
			||||||
- Improved the resource handling when loading models.
 | 
					- Improved the resource handling when loading models.
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user