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,161 @@
using System.Text.Json;
namespace StellaOps.AdvisoryAI.UnifiedSearch;
public sealed record UnifiedChunk(
string ChunkId,
string DocId,
string Kind,
string Domain,
string Title,
string Body,
float[]? Embedding,
string? EntityKey,
string? EntityType,
string? Anchor,
string? SectionPath,
int SpanStart,
int SpanEnd,
DateTimeOffset? Freshness,
JsonDocument Metadata);
public sealed record UnifiedSearchRequest(
string Q,
int? K = null,
UnifiedSearchFilter? Filters = null,
bool IncludeSynthesis = true,
bool IncludeDebug = false);
public sealed record UnifiedSearchFilter
{
public IReadOnlyList<string>? Domains { get; init; }
public IReadOnlyList<string>? EntityTypes { get; init; }
public string? EntityKey { get; init; }
public string? Product { get; init; }
public string? Version { get; init; }
public string? Service { get; init; }
public IReadOnlyList<string>? Tags { get; init; }
public string? Tenant { get; init; }
/// <summary>
/// User scopes extracted from the authenticated request context. Used by
/// <c>DomainWeightCalculator</c> to apply role-based domain biases (Sprint 106 / G6).
/// Not serialized in API responses.
/// </summary>
public IReadOnlyList<string>? UserScopes { get; init; }
}
public sealed record SearchSuggestion(string Text, string Reason);
public sealed record SearchRefinement(string Text, string Source);
public sealed record UnifiedSearchResponse(
string Query,
int TopK,
IReadOnlyList<EntityCard> Cards,
SynthesisResult? Synthesis,
UnifiedSearchDiagnostics Diagnostics,
IReadOnlyList<SearchSuggestion>? Suggestions = null,
IReadOnlyList<SearchRefinement>? Refinements = null);
public sealed record EntityCard
{
public string EntityKey { get; init; } = string.Empty;
public string EntityType { get; init; } = string.Empty;
public string Domain { get; init; } = "knowledge";
public string Title { get; init; } = string.Empty;
public string Snippet { get; init; } = string.Empty;
public double Score { get; init; }
public string? Severity { get; init; }
public IReadOnlyList<EntityCardAction> Actions { get; init; } = [];
public IReadOnlyDictionary<string, string>? Metadata { get; init; }
public IReadOnlyList<string> Sources { get; init; } = [];
public EntityCardPreview? Preview { get; init; }
}
public sealed record EntityCardPreview(
string ContentType,
string Content,
string? Language = null,
IReadOnlyList<PreviewField>? StructuredFields = null);
public sealed record PreviewField(string Label, string Value, string? Severity = null);
public sealed record EntityCardAction(
string Label,
string ActionType,
string? Route = null,
string? Command = null,
bool IsPrimary = false);
public sealed record SynthesisResult
{
public string Summary { get; init; } = string.Empty;
public string Template { get; init; } = string.Empty;
public string Confidence { get; init; } = "low";
public int SourceCount { get; init; }
public IReadOnlyList<string> DomainsCovered { get; init; } = [];
public IReadOnlyList<SynthesisCitation>? Citations { get; init; }
public double? GroundingScore { get; init; }
}
public sealed record SynthesisCitation
{
public int Index { get; init; }
public string EntityKey { get; init; } = string.Empty;
public string Title { get; init; } = string.Empty;
}
public sealed record UnifiedSearchDiagnostics(
int FtsMatches,
int VectorMatches,
int EntityCardCount,
long DurationMs,
bool UsedVector,
string Mode,
QueryPlan? Plan = null);
public sealed record QueryPlan
{
public string OriginalQuery { get; init; } = string.Empty;
public string NormalizedQuery { get; init; } = string.Empty;
public string Intent { get; init; } = "explore";
public IReadOnlyList<EntityMention> DetectedEntities { get; init; } = [];
public IReadOnlyDictionary<string, double> DomainWeights { get; init; } =
new Dictionary<string, double>(StringComparer.Ordinal);
}
public sealed record EntityMention(
string Value,
string EntityType,
int StartIndex,
int Length);