mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-22 13:35:01 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eccf65f0a6 | ||
|
|
2429788ccc | ||
|
|
0125f48f61 | ||
|
|
94028b2c06 | ||
|
|
c5acce7278 |
No files matched your search
@@ -199,7 +199,7 @@ public sealed class AgentDataSourceSelection (ILogger<AgentDataSourceSelection>
|
|||||||
// Call the ERI server to get the server description:
|
// Call the ERI server to get the server description:
|
||||||
//
|
//
|
||||||
using var eriClient = ERIClientFactory.Get(eriDataSource.Version, eriDataSource)!;
|
using var eriClient = ERIClientFactory.Get(eriDataSource.Version, eriDataSource)!;
|
||||||
var authResponse = await eriClient.AuthenticateAsync(eriDataSource, rustService, token);
|
var authResponse = await eriClient.AuthenticateAsync(rustService, cancellationToken: token);
|
||||||
if (authResponse.Successful)
|
if (authResponse.Successful)
|
||||||
{
|
{
|
||||||
var serverDescriptionResponse = await eriClient.GetDataSourceInfoAsync(token);
|
var serverDescriptionResponse = await eriClient.GetDataSourceInfoAsync(token);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ public partial class Changelog
|
|||||||
|
|
||||||
public static readonly Log[] LOGS =
|
public static readonly Log[] LOGS =
|
||||||
[
|
[
|
||||||
|
new (209, "v0.9.34, build 209 (2025-03-11 13:02 UTC)", "v0.9.34.md"),
|
||||||
|
new (208, "v0.9.33, build 208 (2025-03-11 08:14 UTC)", "v0.9.33.md"),
|
||||||
new (207, "v0.9.32, build 207 (2025-03-08 20:15 UTC)", "v0.9.32.md"),
|
new (207, "v0.9.32, build 207 (2025-03-08 20:15 UTC)", "v0.9.32.md"),
|
||||||
new (206, "v0.9.31, build 206 (2025-03-03 15:33 UTC)", "v0.9.31.md"),
|
new (206, "v0.9.31, build 206 (2025-03-03 15:33 UTC)", "v0.9.31.md"),
|
||||||
new (205, "v0.9.30, build 205 (2025-02-24 19:55 UTC)", "v0.9.30.md"),
|
new (205, "v0.9.30, build 205 (2025-02-24 19:55 UTC)", "v0.9.30.md"),
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public partial class DataSourceERI_V1InfoDialog : ComponentBase, IAsyncDisposabl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginResult = await client.AuthenticateAsync(this.DataSource, this.RustService);
|
var loginResult = await client.AuthenticateAsync(this.RustService);
|
||||||
if (!loginResult.Successful)
|
if (!loginResult.Successful)
|
||||||
{
|
{
|
||||||
this.dataIssues.Add(loginResult.Message);
|
this.dataIssues.Add(loginResult.Message);
|
||||||
|
|||||||
@@ -188,13 +188,8 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(14));
|
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(14));
|
||||||
var dataSource = new DataSourceERI_V1
|
this.DataSource = this.CreateDataSource();
|
||||||
{
|
using var client = ERIClientFactory.Get(ERIVersion.V1, this.DataSource);
|
||||||
Hostname = this.dataHostname,
|
|
||||||
Port = this.dataPort
|
|
||||||
};
|
|
||||||
|
|
||||||
using var client = ERIClientFactory.Get(ERIVersion.V1, dataSource);
|
|
||||||
if(client is null)
|
if(client is null)
|
||||||
{
|
{
|
||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
@@ -216,7 +211,7 @@ public partial class DataSourceERI_V1Dialog : ComponentBase, ISecretId
|
|||||||
|
|
||||||
this.availableAuthMethods = authSchemes.Data!.Select(n => n.AuthMethod).ToList();
|
this.availableAuthMethods = authSchemes.Data!.Select(n => n.AuthMethod).ToList();
|
||||||
|
|
||||||
var loginResult = await client.AuthenticateAsync(this.DataSource, this.RustService, cts.Token);
|
var loginResult = await client.AuthenticateAsync(this.RustService, this.dataSecret, cts.Token);
|
||||||
if (!loginResult.Successful)
|
if (!loginResult.Successful)
|
||||||
{
|
{
|
||||||
await this.form.Validate();
|
await this.form.Validate();
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
var logger = Program.SERVICE_PROVIDER.GetRequiredService<ILogger<DataSourceERI_V1>>();
|
var logger = Program.SERVICE_PROVIDER.GetRequiredService<ILogger<DataSourceERI_V1>>();
|
||||||
|
|
||||||
using var eriClient = ERIClientFactory.Get(this.Version, this)!;
|
using var eriClient = ERIClientFactory.Get(this.Version, this)!;
|
||||||
var authResponse = await eriClient.AuthenticateAsync(this, rustService, token);
|
var authResponse = await eriClient.AuthenticateAsync(rustService, cancellationToken: token);
|
||||||
if (authResponse.Successful)
|
if (authResponse.Successful)
|
||||||
{
|
{
|
||||||
var retrievalRequest = new RetrievalRequest
|
var retrievalRequest = new RetrievalRequest
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
using AIStudio.Settings;
|
||||||
|
|
||||||
namespace AIStudio.Tools.ERIClient;
|
namespace AIStudio.Tools.ERIClient;
|
||||||
|
|
||||||
public abstract class ERIClientBase(string baseAddress) : IDisposable
|
public abstract class ERIClientBase(IERIDataSource dataSource) : IDisposable
|
||||||
{
|
{
|
||||||
|
protected readonly IERIDataSource dataSource = dataSource;
|
||||||
|
|
||||||
protected static readonly JsonSerializerOptions JSON_OPTIONS = new()
|
protected static readonly JsonSerializerOptions JSON_OPTIONS = new()
|
||||||
{
|
{
|
||||||
WriteIndented = true,
|
WriteIndented = true,
|
||||||
@@ -21,7 +25,7 @@ public abstract class ERIClientBase(string baseAddress) : IDisposable
|
|||||||
|
|
||||||
protected readonly HttpClient httpClient = new()
|
protected readonly HttpClient httpClient = new()
|
||||||
{
|
{
|
||||||
BaseAddress = new Uri(baseAddress),
|
BaseAddress = new Uri($"{dataSource.Hostname}:{dataSource.Port}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected string securityToken = string.Empty;
|
protected string securityToken = string.Empty;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ public static class ERIClientFactory
|
|||||||
{
|
{
|
||||||
public static IERIClient? Get(ERIVersion version, IERIDataSource dataSource) => version switch
|
public static IERIClient? Get(ERIVersion version, IERIDataSource dataSource) => version switch
|
||||||
{
|
{
|
||||||
ERIVersion.V1 => new ERIClientV1($"{dataSource.Hostname}:{dataSource.Port}"),
|
ERIVersion.V1 => new ERIClientV1(dataSource),
|
||||||
|
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using AIStudio.Tools.Services;
|
|||||||
|
|
||||||
namespace AIStudio.Tools.ERIClient;
|
namespace AIStudio.Tools.ERIClient;
|
||||||
|
|
||||||
public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIClient
|
public class ERIClientV1(IERIDataSource dataSource) : ERIClientBase(dataSource), IERIClient
|
||||||
{
|
{
|
||||||
#region Implementation of IERIClient
|
#region Implementation of IERIClient
|
||||||
|
|
||||||
@@ -59,13 +59,13 @@ public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<APIResponse<AuthResponse>> AuthenticateAsync(IERIDataSource dataSource, RustService rustService, CancellationToken cancellationToken = default)
|
public async Task<APIResponse<AuthResponse>> AuthenticateAsync(RustService rustService, string? temporarySecret = null, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var authMethod = dataSource.AuthMethod;
|
var authMethod = this.dataSource.AuthMethod;
|
||||||
var username = dataSource.Username;
|
var username = this.dataSource.Username;
|
||||||
switch (dataSource.AuthMethod)
|
switch (this.dataSource.AuthMethod)
|
||||||
{
|
{
|
||||||
case AuthMethod.NONE:
|
case AuthMethod.NONE:
|
||||||
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
|
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
|
||||||
@@ -99,17 +99,24 @@ public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIC
|
|||||||
}
|
}
|
||||||
|
|
||||||
case AuthMethod.USERNAME_PASSWORD:
|
case AuthMethod.USERNAME_PASSWORD:
|
||||||
var passwordResponse = await rustService.GetSecret(dataSource);
|
string password;
|
||||||
if (!passwordResponse.Success)
|
if (string.IsNullOrWhiteSpace(temporarySecret))
|
||||||
{
|
{
|
||||||
return new()
|
var passwordResponse = await rustService.GetSecret(this.dataSource);
|
||||||
|
if (!passwordResponse.Success)
|
||||||
{
|
{
|
||||||
Successful = false,
|
return new()
|
||||||
Message = "Failed to retrieve the password."
|
{
|
||||||
};
|
Successful = false,
|
||||||
}
|
Message = "Failed to retrieve the password."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
password = await passwordResponse.Secret.Decrypt(Program.ENCRYPTION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
password = temporarySecret;
|
||||||
|
|
||||||
var password = await passwordResponse.Secret.Decrypt(Program.ENCRYPTION);
|
|
||||||
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
|
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
|
||||||
{
|
{
|
||||||
// We must send both values inside the header. The username field is named 'user'.
|
// We must send both values inside the header. The username field is named 'user'.
|
||||||
@@ -146,17 +153,24 @@ public class ERIClientV1(string baseAddress) : ERIClientBase(baseAddress), IERIC
|
|||||||
}
|
}
|
||||||
|
|
||||||
case AuthMethod.TOKEN:
|
case AuthMethod.TOKEN:
|
||||||
var tokenResponse = await rustService.GetSecret(dataSource);
|
string token;
|
||||||
if (!tokenResponse.Success)
|
if (string.IsNullOrWhiteSpace(temporarySecret))
|
||||||
{
|
{
|
||||||
return new()
|
var tokenResponse = await rustService.GetSecret(this.dataSource);
|
||||||
|
if (!tokenResponse.Success)
|
||||||
{
|
{
|
||||||
Successful = false,
|
return new()
|
||||||
Message = "Failed to retrieve the access token."
|
{
|
||||||
};
|
Successful = false,
|
||||||
}
|
Message = "Failed to retrieve the access token."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
token = await tokenResponse.Secret.Decrypt(Program.ENCRYPTION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
token = temporarySecret;
|
||||||
|
|
||||||
var token = await tokenResponse.Secret.Decrypt(Program.ENCRYPTION);
|
|
||||||
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
|
using (var request = new HttpRequestMessage(HttpMethod.Post, $"auth?authMethod={authMethod}"))
|
||||||
{
|
{
|
||||||
request.Headers.Add("Authorization", $"Bearer {token}");
|
request.Headers.Add("Authorization", $"Bearer {token}");
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using AIStudio.Settings;
|
|
||||||
using AIStudio.Tools.ERIClient.DataModel;
|
using AIStudio.Tools.ERIClient.DataModel;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
@@ -19,11 +18,11 @@ public interface IERIClient : IDisposable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Authenticate the user to the ERI server.
|
/// Authenticate the user to the ERI server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataSource">The data source to use.</param>
|
|
||||||
/// <param name="rustService">The Rust service.</param>
|
/// <param name="rustService">The Rust service.</param>
|
||||||
|
/// <param name="temporarySecret">The temporary secret when adding a new data source, and the secret is not yet stored in the OS.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>The authentication response.</returns>
|
/// <returns>The authentication response.</returns>
|
||||||
public Task<APIResponse<AuthResponse>> AuthenticateAsync(IERIDataSource dataSource, RustService rustService, CancellationToken cancellationToken = default);
|
public Task<APIResponse<AuthResponse>> AuthenticateAsync(RustService rustService, string? temporarySecret = null, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the data source information from the ERI server.
|
/// Retrieves the data source information from the ERI server.
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public sealed class DataSourceService
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.LogInformation($"Authenticating with ERI source '{source.Name}' (id={source.Id})...");
|
this.logger.LogInformation($"Authenticating with ERI source '{source.Name}' (id={source.Id})...");
|
||||||
var loginResult = await client.AuthenticateAsync(eriSource, this.rustService, cancellationTokenSource.Token);
|
var loginResult = await client.AuthenticateAsync(this.rustService, cancellationToken: cancellationTokenSource.Token);
|
||||||
if (!loginResult.Successful)
|
if (!loginResult.Successful)
|
||||||
{
|
{
|
||||||
this.logger.LogWarning($"Authentication with ERI source '{source.Name}' (id={source.Id}) failed. We skip this source. Reason: {loginResult.Message}");
|
this.logger.LogWarning($"Authentication with ERI source '{source.Name}' (id={source.Id}) failed. We skip this source. Reason: {loginResult.Message}");
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# v0.9.33, build 208 (2025-03-11 08:14 UTC)
|
||||||
|
- Fixed a bug where the authentication methods for added ERI servers were not applied correctly. Thanks Kerstin `KeSah001` for reporting this issue.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# v0.9.34, build 209 (2025-03-11 13:02 UTC)
|
||||||
|
- Fixed another bug related to ERI server authentication when adding new servers.
|
||||||
+4
-4
@@ -1,9 +1,9 @@
|
|||||||
0.9.32
|
0.9.34
|
||||||
2025-03-08 20:15:02 UTC
|
2025-03-11 13:02:01 UTC
|
||||||
207
|
209
|
||||||
8.0.113 (commit 8f216348dc)
|
8.0.113 (commit 8f216348dc)
|
||||||
8.0.13 (commit eba546b0f0)
|
8.0.13 (commit eba546b0f0)
|
||||||
1.85.0 (commit 4d91de4e4)
|
1.85.0 (commit 4d91de4e4)
|
||||||
7.16.0
|
7.16.0
|
||||||
1.8.1
|
1.8.1
|
||||||
5a726577ca2, release
|
2429788ccc0, release
|
||||||
Generated
+1
-1
@@ -2350,7 +2350,7 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mindwork-ai-studio"
|
name = "mindwork-ai-studio"
|
||||||
version = "0.9.32"
|
version = "0.9.34"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"arboard",
|
"arboard",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mindwork-ai-studio"
|
name = "mindwork-ai-studio"
|
||||||
version = "0.9.32"
|
version = "0.9.34"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "MindWork AI Studio"
|
description = "MindWork AI Studio"
|
||||||
authors = ["Thorsten Sommer"]
|
authors = ["Thorsten Sommer"]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "MindWork AI Studio",
|
"productName": "MindWork AI Studio",
|
||||||
"version": "0.9.32"
|
"version": "0.9.34"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
Reference in new issue
Block a user