search and ai stabilization work, localization stablized.

This commit is contained in:
master
2026-02-24 23:29:36 +02:00
parent 4f947a8b61
commit b07d27772e
766 changed files with 55299 additions and 3221 deletions

View File

@@ -0,0 +1,69 @@
using Microsoft.Extensions.Logging;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
namespace StellaOps.AdvisoryAI.UnifiedSearch;
public sealed record UnifiedSearchTelemetryEvent(
string Tenant,
string QueryHash,
string Intent,
int ResultCount,
long DurationMs,
bool UsedVector,
IReadOnlyDictionary<string, double> DomainWeights,
IReadOnlyList<string> TopDomains);
public interface IUnifiedSearchTelemetrySink
{
void Record(UnifiedSearchTelemetryEvent telemetryEvent);
}
internal sealed class LoggingUnifiedSearchTelemetrySink : IUnifiedSearchTelemetrySink
{
private readonly ILogger<LoggingUnifiedSearchTelemetrySink> _logger;
public LoggingUnifiedSearchTelemetrySink(ILogger<LoggingUnifiedSearchTelemetrySink> logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public void Record(UnifiedSearchTelemetryEvent telemetryEvent)
{
ArgumentNullException.ThrowIfNull(telemetryEvent);
var weights = string.Join(
",",
telemetryEvent.DomainWeights
.OrderBy(static pair => pair.Key, StringComparer.Ordinal)
.Select(static pair => $"{pair.Key}:{pair.Value.ToString("F3", CultureInfo.InvariantCulture)}"));
var topDomains = telemetryEvent.TopDomains.Count == 0
? "-"
: string.Join(",", telemetryEvent.TopDomains.OrderBy(static value => value, StringComparer.Ordinal));
_logger.LogInformation(
"unified_search telemetry tenant={Tenant} query_hash={QueryHash} intent={Intent} results={ResultCount} duration_ms={DurationMs} used_vector={UsedVector} top_domains={TopDomains} weights={Weights}",
telemetryEvent.Tenant,
telemetryEvent.QueryHash,
telemetryEvent.Intent,
telemetryEvent.ResultCount,
telemetryEvent.DurationMs,
telemetryEvent.UsedVector,
topDomains,
weights);
}
}
internal static class UnifiedSearchTelemetryHash
{
public static string HashQuery(string query)
{
ArgumentNullException.ThrowIfNull(query);
var bytes = Encoding.UTF8.GetBytes(query);
var hash = SHA256.HashData(bytes);
return Convert.ToHexString(hash).ToLowerInvariant();
}
}