Skip to content

Commit 2d95c05

Browse files
Remove Create factory method on AuAuditLog as now covered by the AiAuditLogFactory
1 parent ad4c3bf commit 2d95c05

1 file changed

Lines changed: 0 additions & 119 deletions

File tree

Umbraco.Ai/src/Umbraco.Ai.Core/AuditLog/AiAuditLog.cs

Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
using System.Text.RegularExpressions;
2-
using Microsoft.Extensions.AI;
3-
using Microsoft.Extensions.Logging;
41
using Umbraco.Ai.Core.Models;
5-
using Umbraco.Cms.Core.Models.Membership;
62

73
namespace Umbraco.Ai.Core.AuditLog;
84

@@ -144,119 +140,4 @@ public sealed class AiAuditLog
144140
/// Stored as a JSON dictionary in the database.
145141
/// </summary>
146142
public IReadOnlyDictionary<string, string>? Metadata { get; init; }
147-
148-
/// <summary>
149-
/// Creates a new AiAuditLog instance from the given AiAuditContext.
150-
/// </summary>
151-
/// <param name="context">The AiAuditContext containing operation details.</param>
152-
/// <param name="options">The AiAuditLogOptions for configuring audit-log behavior.</param>
153-
/// <param name="metadata">Optional metadata to include in the audit-log.</param>
154-
/// <param name="detailLevel">The detail level for this audit-log.</param>
155-
/// <param name="user">The user who initiated the operation.</param>
156-
/// <param name="id">Optional specific ID for the audit-log; a new GUID will be generated if not provided.</param>
157-
/// <param name="parentId">Optional parent audit-log ID if this log is part of a nested operation.</param>
158-
/// <param name="loggerFactory">Optional logger factory for logging during creation.</param>
159-
/// <returns></returns>
160-
public static AiAuditLog Create(
161-
AiAuditContext context,
162-
AiAuditLogOptions options,
163-
IReadOnlyDictionary<string, string>? metadata = null,
164-
AiAuditLogDetailLevel detailLevel = AiAuditLogDetailLevel.FailuresOnly,
165-
IUser? user = null,
166-
Guid? id = null,
167-
Guid? parentId = null,
168-
ILoggerFactory? loggerFactory = null)
169-
{
170-
if (!context.ProfileId.HasValue) throw new ArgumentException("ProfileId must be set in the AiAuditContext.", nameof(context));
171-
if (string.IsNullOrWhiteSpace(context.ProfileAlias)) throw new ArgumentException("ProfileAlias must be set in the AiAuditContext.", nameof(context));
172-
if (string.IsNullOrWhiteSpace(context.ProviderId)) throw new ArgumentException("ProviderId must be set in the AiAuditContext.", nameof(context));
173-
if (string.IsNullOrWhiteSpace(context.ModelId)) throw new ArgumentException("ModelId must be set in the AiAuditContext.", nameof(context));
174-
175-
var auditLog = new AiAuditLog
176-
{
177-
Id = id ?? Guid.NewGuid(),
178-
StartTime = DateTime.UtcNow,
179-
ParentAuditLogId = parentId,
180-
UserId = user?.Id.ToString(),
181-
UserName = user?.Name,
182-
Capability = context.Capability,
183-
ProfileId = context.ProfileId.Value,
184-
ProfileAlias = context.ProfileAlias,
185-
ProviderId = context.ProviderId,
186-
ModelId = context.ModelId,
187-
EntityId = context.EntityId,
188-
EntityType = context.EntityType,
189-
FeatureType = context.FeatureType,
190-
FeatureId = context.FeatureId,
191-
Metadata = metadata != null
192-
? new Dictionary<string, string>(metadata)
193-
: null,
194-
DetailLevel = detailLevel
195-
};
196-
197-
// Set initial status to Running
198-
auditLog.Status = AiAuditLogStatus.Running;
199-
200-
var logger = loggerFactory?.CreateLogger<AiAuditLog>();
201-
202-
// Capture response snapshot if configured
203-
if (options.PersistPrompts && context.Prompt is not null)
204-
{
205-
var prompt = FormatPromptSnapshot(context.Prompt, context.Capability);
206-
prompt = ApplyRedaction(options, prompt, logger);
207-
auditLog.PromptSnapshot = prompt;
208-
logger?.LogDebug("Captured prompt snapshot for audit-log {AuditLogId}: {Length} characters",
209-
auditLog.Id, prompt?.Length ?? 0);
210-
}
211-
212-
return auditLog;
213-
}
214-
215-
private static string? FormatPromptSnapshot(object? promptObj, AiCapability capability)
216-
{
217-
if (promptObj is null)
218-
{
219-
return null;
220-
}
221-
222-
try
223-
{
224-
return capability switch
225-
{
226-
AiCapability.Chat when promptObj is IEnumerable<ChatMessage> messages =>
227-
string.Join("\n", messages.Select(m => $"[{m.Role}] {m.Text}")),
228-
229-
AiCapability.Embedding when promptObj is IEnumerable<string> values =>
230-
string.Join("\n", values.Select((v, i) => $"[{i}] {v}")),
231-
232-
_ => promptObj.ToString()
233-
};
234-
}
235-
catch
236-
{
237-
// If formatting fails, return a fallback representation
238-
return $"[Unable to format {capability} prompt]";
239-
}
240-
}
241-
242-
private static string? ApplyRedaction(AiAuditLogOptions options, string? input,
243-
ILogger<AiAuditLog>? logger = null)
244-
{
245-
if (string.IsNullOrEmpty(input) || options.RedactionPatterns.Count == 0)
246-
return input;
247-
248-
var result = input;
249-
foreach (var pattern in options.RedactionPatterns)
250-
{
251-
try
252-
{
253-
result = Regex.Replace(result, pattern, "[REDACTED]", RegexOptions.IgnoreCase);
254-
}
255-
catch (Exception ex)
256-
{
257-
logger?.LogWarning(ex, "Failed to apply redaction pattern: {Pattern}", pattern);
258-
}
259-
}
260-
return result;
261-
}
262143
}

0 commit comments

Comments
 (0)