Skip to content

Commit 7c72905

Browse files
committed
Merge pull request LykosAI#1162 from ionite34/fix-civit
(cherry picked from commit 2b6773a08161299068444289de646348fe615140)
1 parent c2f649f commit 7c72905

File tree

5 files changed

+88
-14
lines changed

5 files changed

+88
-14
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to Stability Matrix will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).
77

8+
## v2.15.3
9+
### Fixed
10+
- Fixed [#1424](https://github.com/LykosAI/StabilityMatrix/issues/1424) - Civitai account 401 error when connecting accounts, updated for new API changes
11+
812
## v2.15.2
913
### Changed
1014
- Updated Avalonia to 11.3.7

StabilityMatrix.Avalonia/Services/AccountsService.cs

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ public async Task CivitLoginAsync(string apiToken)
172172
var secrets = await secretsManager.SafeLoadAsync();
173173

174174
// Get id first using the api token
175-
var userAccount = await civitTRPCApi.GetUserAccountDefault(apiToken);
176-
var id = userAccount.Result.Data.Json.Id;
175+
var userAccount = await civitTRPCApi.GetUserAccount(bearerToken: apiToken);
176+
var id =
177+
userAccount.InnerJson?.Id
178+
?? throw new InvalidOperationException("GetUserAccount did not contain an id");
177179

178180
// Then get the username using the id
179181
var account = await civitTRPCApi.GetUserById(new CivitGetUserByIdRequest { Id = id }, apiToken);
@@ -241,7 +243,7 @@ secrets.LykosAccountV2 is not null
241243
{
242244
IsConnected = true,
243245
Principal = principal,
244-
User = user
246+
User = user,
245247
}
246248
);
247249

@@ -282,27 +284,55 @@ private async Task RefreshHuggingFaceAsync(Secrets secrets)
282284
if (response.IsSuccessStatusCode && response.Content != null)
283285
{
284286
// Token is valid, user info fetched
285-
logger.LogInformation("Hugging Face token is valid. User: {Username}", response.Content.Name);
286-
OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(true, response.Content.Name));
287+
logger.LogInformation(
288+
"Hugging Face token is valid. User: {Username}",
289+
response.Content.Name
290+
);
291+
OnHuggingFaceAccountStatusUpdate(
292+
new HuggingFaceAccountStatusUpdateEventArgs(true, response.Content.Name)
293+
);
287294
}
288295
else
289296
{
290297
// Token is likely invalid or other API error
291-
logger.LogWarning("Hugging Face token validation failed. Status: {StatusCode}, Error: {Error}, Content: {Content}", response.StatusCode, response.Error?.ToString(), await response.Error?.GetContentAsAsync<string>() ?? "N/A");
292-
OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(false, null, $"Token validation failed: {response.StatusCode}"));
298+
logger.LogWarning(
299+
"Hugging Face token validation failed. Status: {StatusCode}, Error: {Error}, Content: {Content}",
300+
response.StatusCode,
301+
response.Error?.ToString(),
302+
await response.Error?.GetContentAsAsync<string>() ?? "N/A"
303+
);
304+
OnHuggingFaceAccountStatusUpdate(
305+
new HuggingFaceAccountStatusUpdateEventArgs(
306+
false,
307+
null,
308+
$"Token validation failed: {response.StatusCode}"
309+
)
310+
);
293311
}
294312
}
295313
catch (ApiException apiEx)
296314
{
297315
// Handle Refit's ApiException (network issues, non-success status codes not caught by IsSuccessStatusCode if IApiResponse isn't used directly)
298-
logger.LogError(apiEx, "Hugging Face API request failed during token validation. Content: {Content}", await apiEx.GetContentAsAsync<string>() ?? "N/A");
299-
OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(false, null, "API request failed during token validation."));
316+
logger.LogError(
317+
apiEx,
318+
"Hugging Face API request failed during token validation. Content: {Content}",
319+
await apiEx.GetContentAsAsync<string>() ?? "N/A"
320+
);
321+
OnHuggingFaceAccountStatusUpdate(
322+
new HuggingFaceAccountStatusUpdateEventArgs(
323+
false,
324+
null,
325+
"API request failed during token validation."
326+
)
327+
);
300328
}
301329
catch (Exception ex)
302330
{
303331
// Handle other unexpected errors
304332
logger.LogError(ex, "An unexpected error occurred during Hugging Face token validation.");
305-
OnHuggingFaceAccountStatusUpdate(new HuggingFaceAccountStatusUpdateEventArgs(false, null, "An unexpected error occurred."));
333+
OnHuggingFaceAccountStatusUpdate(
334+
new HuggingFaceAccountStatusUpdateEventArgs(false, null, "An unexpected error occurred.")
335+
);
306336
}
307337
}
308338
else
@@ -390,7 +420,10 @@ private void OnHuggingFaceAccountStatusUpdate(HuggingFaceAccountStatusUpdateEven
390420
else if (e.IsConnected && HuggingFaceStatus?.IsConnected == false)
391421
{
392422
// Assuming Username might be null for now as we are not fetching it.
393-
logger.LogInformation("Hugging Face account connected" + (string.IsNullOrWhiteSpace(e.Username) ? "" : $" (User: {e.Username})"));
423+
logger.LogInformation(
424+
"Hugging Face account connected"
425+
+ (string.IsNullOrWhiteSpace(e.Username) ? "" : $" (User: {e.Username})")
426+
);
394427
}
395428
else if (!e.IsConnected && !string.IsNullOrWhiteSpace(e.ErrorMessage))
396429
{

StabilityMatrix.Avalonia/StabilityMatrix.Avalonia.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
88
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
99
<ApplicationIcon>./Assets/Icon.ico</ApplicationIcon>
10-
<Version>2.15.0-dev.999</Version>
10+
<Version>2.16.0-dev.999</Version>
1111
<InformationalVersion>$(Version)</InformationalVersion>
1212
<EnableWindowsTargeting>true</EnableWindowsTargeting>
1313
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

StabilityMatrix.Core/Api/ICivitTRPCApi.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,25 @@ Task<CivitUserProfileResponse> GetUserProfile(
2020

2121
[QueryUriFormat(UriFormat.UriEscaped)]
2222
[Get("/api/trpc/buzz.getUserAccount")]
23-
Task<CivitTrpcResponse<CivitUserAccountResponse>> GetUserAccount(
23+
Task<CivitTrpcArrayResponse<CivitUserAccountResponse>> GetUserAccount(
2424
[Query] string input,
2525
[Authorize] string bearerToken,
2626
CancellationToken cancellationToken = default
2727
);
2828

29-
Task<CivitTrpcResponse<CivitUserAccountResponse>> GetUserAccountDefault(
29+
[QueryUriFormat(UriFormat.UriEscaped)]
30+
[Get("/api/trpc/buzz.getUserAccount")]
31+
Task<CivitTrpcArrayResponse<CivitUserAccountResponse>> GetUserAccount(
32+
[Authorize] string bearerToken,
33+
CancellationToken cancellationToken = default
34+
);
35+
36+
/// <summary>
37+
/// Calls <see cref="GetUserAccount(string, string, CancellationToken)"/> with default JSON input.
38+
/// Not required and returns 401 since Oct 2025 since civit changes.
39+
/// Mainly just use <see cref="GetUserAccount(string, CancellationToken)"/> instead.
40+
/// </summary>
41+
Task<CivitTrpcArrayResponse<CivitUserAccountResponse>> GetUserAccountDefault(
3042
string bearerToken,
3143
CancellationToken cancellationToken = default
3244
)

StabilityMatrix.Core/Models/Api/CivitTRPC/CivitUserAccountResponse.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,28 @@ public record CivitTrpcResponseDataJson<TJson>
2121
public required TJson Json { get; set; }
2222
}
2323
}
24+
25+
/// <summary>
26+
/// Like CivitTrpcResponse, but wrapped as the first item of an array.
27+
/// </summary>
28+
/// <typeparam name="T"></typeparam>
29+
public record CivitTrpcArrayResponse<T>
30+
{
31+
[JsonPropertyName("result")]
32+
public required CivitTrpcResponseData<T> Result { get; set; }
33+
34+
[JsonIgnore]
35+
public T? InnerJson => Result.Data.Json.FirstOrDefault();
36+
37+
public record CivitTrpcResponseData<TData>
38+
{
39+
[JsonPropertyName("data")]
40+
public required CivitTrpcResponseDataJson<TData> Data { get; set; }
41+
}
42+
43+
public record CivitTrpcResponseDataJson<TJson>
44+
{
45+
[JsonPropertyName("Json")]
46+
public required List<TJson> Json { get; set; }
47+
}
48+
}

0 commit comments

Comments
 (0)