2025-02-09 11:36:37 +00:00
using System.Text ;
using System.Text.Json ;
using AIStudio.Settings ;
using AIStudio.Tools.ERIClient.DataModel ;
2025-02-15 14:41:12 +00:00
using AIStudio.Tools.Services ;
2025-02-09 11:36:37 +00:00
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 )
{
2025-02-15 14:41:12 +00:00
try
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
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."
} ;
}
2025-02-09 11:36:37 +00:00
return new ( )
{
2025-02-15 14:41:12 +00:00
Successful = true ,
Data = authMethods
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( TaskCanceledException )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the authentication methods: the request was canceled either by the user or due to a timeout."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( Exception e )
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
return new ( )
{
Successful = false ,
Message = $"Failed to retrieve the authentication methods due to an exception: {e.Message}"
} ;
}
2025-02-09 11:36:37 +00:00
}
public async Task < APIResponse < AuthResponse > > AuthenticateAsync ( IERIDataSource dataSource , RustService rustService , CancellationToken cancellationToken = default )
{
2025-02-15 14:41:12 +00:00
try
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
var authMethod = dataSource . AuthMethod ;
var username = dataSource . Username ;
switch ( dataSource . AuthMethod )
{
case AuthMethod . NONE :
using ( var request = new HttpRequestMessage ( HttpMethod . Post , $"auth?authMethod={authMethod}" ) )
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
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 ;
2025-02-09 11:36:37 +00:00
return new ( )
{
2025-02-15 14:41:12 +00:00
Successful = true ,
Data = noneAuthResult
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
case AuthMethod . USERNAME_PASSWORD :
var passwordResponse = await rustService . GetSecret ( dataSource ) ;
if ( ! passwordResponse . Success )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the password."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
var password = await passwordResponse . Secret . Decrypt ( Program . ENCRYPTION ) ;
using ( var request = new HttpRequestMessage ( HttpMethod . Post , $"auth?authMethod={authMethod}" ) )
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
// 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 ;
2025-02-09 11:36:37 +00:00
return new ( )
{
2025-02-15 14:41:12 +00:00
Successful = true ,
Data = usernamePasswordAuthResult
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
case AuthMethod . TOKEN :
var tokenResponse = await rustService . GetSecret ( dataSource ) ;
if ( ! tokenResponse . Success )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the access token."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
var token = await tokenResponse . Secret . Decrypt ( Program . ENCRYPTION ) ;
using ( var request = new HttpRequestMessage ( HttpMethod . Post , $"auth?authMethod={authMethod}" ) )
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
request . Headers . Add ( "Authorization" , $"Bearer {token}" ) ;
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
using var tokenAuthResponse = await this . httpClient . SendAsync ( request , cancellationToken ) ;
if ( ! tokenAuthResponse . IsSuccessStatusCode )
2025-02-09 11:36:37 +00:00
{
2025-02-15 14:41:12 +00:00
return new ( )
{
Successful = false ,
Message = $"Failed to authenticate with the ERI server. Code: {tokenAuthResponse.StatusCode}, Reason: {tokenAuthResponse.ReasonPhrase}"
} ;
}
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
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 ;
2025-02-09 11:36:37 +00:00
return new ( )
{
2025-02-15 14:41:12 +00:00
Successful = true ,
Data = tokenAuthResult
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
default :
this . securityToken = string . Empty ;
2025-02-09 11:36:37 +00:00
return new ( )
{
2025-02-15 14:41:12 +00:00
Successful = false ,
Message = "The authentication method is not supported yet."
2025-02-09 11:36:37 +00:00
} ;
2025-02-15 14:41:12 +00:00
}
}
catch ( TaskCanceledException )
{
return new ( )
{
Successful = false ,
Message = "Failed to authenticate with the ERI server: the request was canceled either by the user or due to a timeout."
} ;
}
catch ( Exception e )
{
return new ( )
{
Successful = false ,
Message = $"Failed to authenticate with the ERI server due to an exception: {e.Message}"
} ;
2025-02-09 11:36:37 +00:00
}
}
public async Task < APIResponse < DataSourceInfo > > GetDataSourceInfoAsync ( CancellationToken cancellationToken = default )
{
2025-02-15 14:41:12 +00:00
try
{
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."
} ;
}
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
return new ( )
{
Successful = true ,
Data = dataSourceInfo
} ;
}
catch ( TaskCanceledException )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the data source information: the request was canceled either by the user or due to a timeout."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( Exception e )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = $"Failed to retrieve the data source information due to an exception: {e.Message}"
2025-02-09 11:36:37 +00:00
} ;
}
}
public async Task < APIResponse < List < EmbeddingInfo > > > GetEmbeddingInfoAsync ( CancellationToken cancellationToken = default )
{
2025-02-15 14:41:12 +00:00
try
{
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}"
} ;
}
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
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
} ;
}
catch ( TaskCanceledException )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the embedding information: the request was canceled either by the user or due to a timeout."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( Exception e )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = $"Failed to retrieve the embedding information due to an exception: {e.Message}"
2025-02-09 11:36:37 +00:00
} ;
}
}
public async Task < APIResponse < List < RetrievalInfo > > > GetRetrievalInfoAsync ( CancellationToken cancellationToken = default )
{
2025-02-15 14:41:12 +00:00
try
{
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."
} ;
}
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
return new ( )
{
Successful = true ,
Data = retrievalInfo
} ;
}
catch ( TaskCanceledException )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the retrieval information: the request was canceled either by the user or due to a timeout."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( Exception e )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = $"Failed to retrieve the retrieval information due to an exception: {e.Message}"
2025-02-09 11:36:37 +00:00
} ;
}
}
public async Task < APIResponse < List < Context > > > ExecuteRetrievalAsync ( RetrievalRequest request , CancellationToken cancellationToken = default )
{
2025-02-15 14:41:12 +00:00
try
{
using var requestMessage = new HttpRequestMessage ( HttpMethod . Post , "/retrieval" ) ;
requestMessage . Headers . Add ( "token" , this . securityToken ) ;
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
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."
} ;
}
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
return new ( )
{
Successful = true ,
Data = contexts
} ;
}
catch ( TaskCanceledException )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to execute the retrieval request: the request was canceled either by the user or due to a timeout."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( Exception e )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = $"Failed to execute the retrieval request due to an exception: {e.Message}"
2025-02-09 11:36:37 +00:00
} ;
}
}
public async Task < APIResponse < SecurityRequirements > > GetSecurityRequirementsAsync ( CancellationToken cancellationToken = default )
{
2025-02-15 14:41:12 +00:00
try
{
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}"
} ;
}
2025-02-09 11:36:37 +00:00
2025-02-15 14:41:12 +00:00
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
} ;
}
catch ( TaskCanceledException )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = "Failed to retrieve the security requirements: the request was canceled either by the user or due to a timeout."
2025-02-09 11:36:37 +00:00
} ;
}
2025-02-15 14:41:12 +00:00
catch ( Exception e )
2025-02-09 11:36:37 +00:00
{
return new ( )
{
Successful = false ,
2025-02-15 14:41:12 +00:00
Message = $"Failed to retrieve the security requirements due to an exception: {e.Message}"
2025-02-09 11:36:37 +00:00
} ;
}
}
#endregion
}