mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 18:32:12 +00:00
Renamed VisualBriefingJson options
This commit is contained in:
parent
c2d3b410f2
commit
ebb9a6f135
@ -30,9 +30,9 @@ public sealed partial class VisualBriefingArtifactService
|
||||
private const string DATA_ELEMENT_ID = "mwai-briefing-data";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the shared compact JSON configuration.
|
||||
/// Gets the frozen JSON configuration whose bytes the document hash covers.
|
||||
/// </summary>
|
||||
private static readonly JsonSerializerOptions JSON_OPTIONS = VisualBriefingJson.Compact;
|
||||
private static readonly JsonSerializerOptions JSON_OPTIONS = VisualBriefingJson.Canonical;
|
||||
|
||||
/// <summary>
|
||||
/// Defines <c>HtmlLanguageTagRegex</c> for the visual briefing feature.
|
||||
|
||||
@ -380,5 +380,5 @@ public partial class VisualBriefingAssistant
|
||||
this.editor.Author,
|
||||
Settings = this.editor.ToSettings(),
|
||||
Sources = this.editor.ToSources().Select(source => new { source.Path, source.Kind }).ToArray(),
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
}
|
||||
@ -135,12 +135,12 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
||||
authors = "validation",
|
||||
protection = "validation",
|
||||
},
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
|
||||
VisualBriefingCompilerInvariant.Guard(
|
||||
VisualBriefingBuildStage.COMPILATION,
|
||||
VisualBriefingArtifactService.ValidateGeneratedParts(manifest,
|
||||
JsonSerializer.SerializeToElement(validationDataProperties, VisualBriefingJson.Compact),
|
||||
JsonSerializer.SerializeToElement(validationDataProperties, VisualBriefingJson.Canonical),
|
||||
compiled.TemplateHtml, compiled.Css,
|
||||
content.Charts.Count > 0));
|
||||
|
||||
@ -151,7 +151,7 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
||||
ArtifactId = Guid.NewGuid(),
|
||||
CreatedAtUtc = DateTimeOffset.UtcNow,
|
||||
PayloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(previousPresentation.Layout, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(previousPresentation.Layout, VisualBriefingJson.Canonical),
|
||||
previousPresentation.Profile.ToString(),
|
||||
compiled.TemplateHash,
|
||||
compiled.CssHash),
|
||||
|
||||
@ -21,8 +21,8 @@ public sealed class VisualBriefingBuildProgressService
|
||||
public void Publish(VisualBriefingBuildRecord build)
|
||||
{
|
||||
var snapshot = JsonSerializer.Deserialize<VisualBriefingBuildRecord>(
|
||||
JsonSerializer.Serialize(build, VisualBriefingJson.Compact),
|
||||
VisualBriefingJson.Compact)!;
|
||||
JsonSerializer.Serialize(build, VisualBriefingJson.Canonical),
|
||||
VisualBriefingJson.Canonical)!;
|
||||
snapshot.Instruction = string.Empty;
|
||||
this.latest[build.BriefingId] = snapshot;
|
||||
this.Changed?.Invoke(build.BriefingId);
|
||||
|
||||
@ -125,7 +125,7 @@ internal static class VisualBriefingChartCompiler
|
||||
: series,
|
||||
};
|
||||
|
||||
return JsonSerializer.SerializeToElement(option, VisualBriefingJson.Compact);
|
||||
return JsonSerializer.SerializeToElement(option, VisualBriefingJson.Canonical);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -65,19 +65,19 @@ internal sealed class VisualBriefingContentStage(StructuredLlmStageRunner stageR
|
||||
reset = artifact.ResetLabel,
|
||||
brand = "MindWork AI Studio",
|
||||
},
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
|
||||
// Keep in sync with the verification in VisualBriefingStore.ReadContentArtifactAsync:
|
||||
artifact.PayloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(artifact.Slots, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Charts, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Controls, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Formulas, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.AccessibilityTexts, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.SourceReferences, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Slots, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Charts, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Controls, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Formulas, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.AccessibilityTexts, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.SourceReferences, VisualBriefingJson.Canonical),
|
||||
artifact.ResetLabel,
|
||||
JsonSerializer.Serialize(artifact.SourceCoverage, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.AssetPlan, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.SourceCoverage, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.AssetPlan, VisualBriefingJson.Canonical),
|
||||
artifact.StructuralSignature);
|
||||
|
||||
await store.WriteContentArtifactAsync(manifest.BriefingId, artifact, token);
|
||||
@ -170,13 +170,13 @@ internal sealed class VisualBriefingContentStage(StructuredLlmStageRunner stageR
|
||||
Target language: {manifest.Settings.TargetLanguage.PromptGeneralPurpose(manifest.Settings.CustomTargetLanguage)}
|
||||
Audience: {manifest.Settings.AudienceProfile}; {manifest.Settings.AudienceAgeGroup}; {manifest.Settings.AudienceOrganizationalLevel}; {manifest.Settings.AudienceExpertise}
|
||||
Scope instruction: {manifest.Settings.Instruction}
|
||||
Exact planned component IDs: {JsonSerializer.Serialize(componentIds, VisualBriefingJson.Compact)}
|
||||
Exact keys of accessibilityTexts, no others: {JsonSerializer.Serialize(accessibilityTextKeys, VisualBriefingJson.Compact)}
|
||||
Exact required slot IDs with their semantic role and declared type, each to be returned exactly once: {JsonSerializer.Serialize(requiredSlots, VisualBriefingJson.Compact)}
|
||||
Exact chart component IDs, each to receive exactly one chart: {JsonSerializer.Serialize(chartComponentIds, VisualBriefingJson.Compact)}
|
||||
Exact control and formula requirements, no controls for any other component: {JsonSerializer.Serialize(controlRequirements, VisualBriefingJson.Compact)}
|
||||
Plan: {JsonSerializer.Serialize(plan.Sections, VisualBriefingJson.Compact)}
|
||||
Evidence: {JsonSerializer.Serialize(new { evidence.Facts, evidence.Metrics, evidence.Tables, evidence.AssetPlan }, VisualBriefingJson.Compact)}
|
||||
Exact planned component IDs: {JsonSerializer.Serialize(componentIds, VisualBriefingJson.Canonical)}
|
||||
Exact keys of accessibilityTexts, no others: {JsonSerializer.Serialize(accessibilityTextKeys, VisualBriefingJson.Canonical)}
|
||||
Exact required slot IDs with their semantic role and declared type, each to be returned exactly once: {JsonSerializer.Serialize(requiredSlots, VisualBriefingJson.Canonical)}
|
||||
Exact chart component IDs, each to receive exactly one chart: {JsonSerializer.Serialize(chartComponentIds, VisualBriefingJson.Canonical)}
|
||||
Exact control and formula requirements, no controls for any other component: {JsonSerializer.Serialize(controlRequirements, VisualBriefingJson.Canonical)}
|
||||
Plan: {JsonSerializer.Serialize(plan.Sections, VisualBriefingJson.Canonical)}
|
||||
Evidence: {JsonSerializer.Serialize(new { evidence.Facts, evidence.Metrics, evidence.Tables, evidence.AssetPlan }, VisualBriefingJson.Canonical)}
|
||||
""";
|
||||
}
|
||||
|
||||
@ -257,9 +257,9 @@ internal sealed class VisualBriefingContentStage(StructuredLlmStageRunner stageR
|
||||
authors = "validation",
|
||||
protection = "validation",
|
||||
},
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
|
||||
var validationData = JsonSerializer.SerializeToElement(data, VisualBriefingJson.Compact);
|
||||
var validationData = JsonSerializer.SerializeToElement(data, VisualBriefingJson.Canonical);
|
||||
VisualBriefingCompilerInvariant.Guard(VisualBriefingBuildStage.CONTENT,
|
||||
VisualBriefingArtifactService.ValidateGeneratedParts(
|
||||
manifest,
|
||||
@ -353,7 +353,7 @@ internal sealed class VisualBriefingContentStage(StructuredLlmStageRunner stageR
|
||||
ControlId = $"mwai-filter-{index}",
|
||||
ComponentId = component.ComponentId,
|
||||
Kind = VisualBriefingControlKind.FILTER,
|
||||
InitialValue = JsonSerializer.SerializeToElement(SHOW_ALL_VALUE, VisualBriefingJson.Compact),
|
||||
InitialValue = JsonSerializer.SerializeToElement(SHOW_ALL_VALUE, VisualBriefingJson.Canonical),
|
||||
Options = options,
|
||||
};
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ internal static class VisualBriefingData
|
||||
var dictionary = data.EnumerateObject()
|
||||
.Where(property => property.Name is not "_mwai")
|
||||
.ToDictionary(property => property.Name, property => property.Value.Clone(), StringComparer.Ordinal);
|
||||
return JsonSerializer.SerializeToElement(dictionary, VisualBriefingJson.Compact);
|
||||
return JsonSerializer.SerializeToElement(dictionary, VisualBriefingJson.Canonical);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -47,11 +47,11 @@ internal sealed class VisualBriefingEvidenceStage(StructuredLlmStageRunner stage
|
||||
|
||||
var response = run.Response!;
|
||||
var payloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(response.Facts, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(response.Metrics, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(response.Tables, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(response.SourceCoverage, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(response.AssetPlan, VisualBriefingJson.Compact));
|
||||
JsonSerializer.Serialize(response.Facts, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(response.Metrics, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(response.Tables, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(response.SourceCoverage, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(response.AssetPlan, VisualBriefingJson.Canonical));
|
||||
|
||||
var artifact = new VisualBriefingEvidenceArtifact
|
||||
{
|
||||
@ -124,8 +124,8 @@ internal sealed class VisualBriefingEvidenceStage(StructuredLlmStageRunner stage
|
||||
return $"""
|
||||
Target language: {manifest.Settings.TargetLanguage.PromptGeneralPurpose(manifest.Settings.CustomTargetLanguage)}
|
||||
Scope instruction: {manifest.Settings.Instruction}
|
||||
Sources, in the same order as the attached files: {JsonSerializer.Serialize(sources, VisualBriefingJson.Compact)}
|
||||
Media transcripts: {JsonSerializer.Serialize(transcripts, VisualBriefingJson.Compact)}
|
||||
Sources, in the same order as the attached files: {JsonSerializer.Serialize(sources, VisualBriefingJson.Canonical)}
|
||||
Media transcripts: {JsonSerializer.Serialize(transcripts, VisualBriefingJson.Canonical)}
|
||||
""";
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ internal static class VisualBriefingInteractionCompiler
|
||||
controls,
|
||||
state,
|
||||
formulas = formulaMap,
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -16,27 +16,27 @@ namespace AIStudio.Assistants.VisualBriefing;
|
||||
internal static class VisualBriefingJson
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets compact canonical JSON options.
|
||||
/// Gets the frozen options whose byte output is hashed into stored briefings.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Treat these options as frozen. Their exact bytes are hashed into stored briefings: the artifact
|
||||
/// header is serialized into the briefing document, and reading that document back re-serializes the
|
||||
/// header to recompute the document hash. Every build stage likewise hashes its serialized output to
|
||||
/// decide what a later build may reuse. Any change here — a converter, a naming policy, an encoder —
|
||||
/// therefore invalidates every briefing that was ever written, which surfaces as a failed integrity
|
||||
/// check rather than as a build error. This is why enums stay numeric here even though the persisted
|
||||
/// manifest writes their member names.
|
||||
/// header to recompute the document hash. Every build stage likewise hashes its serialized output,
|
||||
/// and a mismatch makes the store discard the stored artifact. Any change here — a converter, a
|
||||
/// naming policy, an encoder — therefore invalidates every briefing that was ever written, which
|
||||
/// surfaces as a failed integrity check rather than as a build error. This is why enums stay numeric
|
||||
/// here even though the persisted manifest writes their member names.
|
||||
/// </remarks>
|
||||
internal static JsonSerializerOptions Compact { get; } = Create(writeIndented: false, enumsAsText: false);
|
||||
internal static JsonSerializerOptions Canonical { get; } = Create(writeIndented: false, enumsAsText: false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets indented persistence JSON options.
|
||||
/// Gets the options for files that are read back by name rather than by hash.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These options are free to evolve, because nothing hashes their output. They write the briefing
|
||||
/// manifest and the diagnostics clipboard text, where readable enum names are worth having.
|
||||
/// </remarks>
|
||||
internal static JsonSerializerOptions Indented { get; } = Create(writeIndented: true, enumsAsText: true);
|
||||
internal static JsonSerializerOptions Persistence { get; } = Create(writeIndented: true, enumsAsText: true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the shared JSON configuration.
|
||||
|
||||
@ -61,7 +61,7 @@ internal sealed class VisualBriefingLayoutCompiler
|
||||
reset = content.ResetLabel,
|
||||
brand = "MindWork AI Studio",
|
||||
},
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
|
||||
var html = CompileNode(layout, sections, components, content, true);
|
||||
var css = CompileCss(profile, layout);
|
||||
|
||||
@ -132,5 +132,5 @@ public sealed class VisualBriefingOperationDiagnostics
|
||||
/// Serializes the diagnostics without user content.
|
||||
/// </summary>
|
||||
/// <returns>A compact JSON document suitable for the clipboard.</returns>
|
||||
public string ToClipboardText() => JsonSerializer.Serialize(this, VisualBriefingJson.Indented);
|
||||
public string ToClipboardText() => JsonSerializer.Serialize(this, VisualBriefingJson.Persistence);
|
||||
}
|
||||
@ -50,7 +50,7 @@ internal sealed class VisualBriefingPlanStage(StructuredLlmStageRunner stageRunn
|
||||
await VisualBriefingEvidenceStage.FailAsync(store, build, stage, run, VisualBriefingValidationRule.REFERENCE_INVALID, token);
|
||||
|
||||
var sections = run.Response!.Sections;
|
||||
var payload = JsonSerializer.Serialize(sections, VisualBriefingJson.Compact);
|
||||
var payload = JsonSerializer.Serialize(sections, VisualBriefingJson.Canonical);
|
||||
|
||||
var structuralSignature = VisualBriefingHashing.Compute(string.Join('\u001f', sections.Select(section => $"{section.SectionId}:{section.Role}:{section.TitleSlotId}:{section.SummarySlotId}")
|
||||
.Concat(sections.SelectMany(section => section.Components)
|
||||
@ -113,6 +113,6 @@ internal sealed class VisualBriefingPlanStage(StructuredLlmStageRunner stageRunn
|
||||
$"""
|
||||
Audience: {manifest.Settings.AudienceProfile}; {manifest.Settings.AudienceAgeGroup}; {manifest.Settings.AudienceOrganizationalLevel}; {manifest.Settings.AudienceExpertise}
|
||||
Scope instruction: {manifest.Settings.Instruction}
|
||||
Evidence: {JsonSerializer.Serialize(new { evidence.Facts, evidence.Metrics, evidence.Tables, evidence.AssetPlan }, VisualBriefingJson.Compact)}
|
||||
Evidence: {JsonSerializer.Serialize(new { evidence.Facts, evidence.Metrics, evidence.Tables, evidence.AssetPlan }, VisualBriefingJson.Canonical)}
|
||||
""";
|
||||
}
|
||||
@ -81,7 +81,7 @@ internal sealed class VisualBriefingPresentationStage(StructuredLlmStageRunner s
|
||||
|
||||
var compiled = VisualBriefingLayoutCompiler.Compile(plan, content, run.Response.Layout, run.Response.Profile);
|
||||
var payloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(run.Response.Layout, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(run.Response.Layout, VisualBriefingJson.Canonical),
|
||||
run.Response.Profile.ToString(),
|
||||
compiled.TemplateHash,
|
||||
compiled.CssHash);
|
||||
@ -114,7 +114,7 @@ internal sealed class VisualBriefingPresentationStage(StructuredLlmStageRunner s
|
||||
|
||||
await store.SaveBuildAsync(build, token);
|
||||
progressService.Publish(build);
|
||||
logger.LogInformation("Visual briefing design completed. OperationId={OperationId} BuildId={BuildId} LayoutHash={LayoutHash} TemplateHash={TemplateHash} CssHash={CssHash}", build.OperationId, build.BuildId, VisualBriefingHashing.Compute(JsonSerializer.Serialize(artifact.Layout, VisualBriefingJson.Compact)), artifact.TemplateHash, artifact.CssHash);
|
||||
logger.LogInformation("Visual briefing design completed. OperationId={OperationId} BuildId={BuildId} LayoutHash={LayoutHash} TemplateHash={TemplateHash} CssHash={CssHash}", build.OperationId, build.BuildId, VisualBriefingHashing.Compute(JsonSerializer.Serialize(artifact.Layout, VisualBriefingJson.Canonical)), artifact.TemplateHash, artifact.CssHash);
|
||||
|
||||
return artifact;
|
||||
}
|
||||
@ -150,9 +150,9 @@ internal sealed class VisualBriefingPresentationStage(StructuredLlmStageRunner s
|
||||
authors = "validation",
|
||||
protection = "validation",
|
||||
},
|
||||
}, VisualBriefingJson.Compact);
|
||||
}, VisualBriefingJson.Canonical);
|
||||
|
||||
var validationData = JsonSerializer.SerializeToElement(data, VisualBriefingJson.Compact);
|
||||
var validationData = JsonSerializer.SerializeToElement(data, VisualBriefingJson.Canonical);
|
||||
VisualBriefingCompilerInvariant.Guard(VisualBriefingBuildStage.DESIGN,
|
||||
VisualBriefingArtifactService.ValidateGeneratedParts(manifest, validationData, compiled.TemplateHtml, compiled.Css, content.Charts.Count > 0));
|
||||
|
||||
@ -187,12 +187,12 @@ internal sealed class VisualBriefingPresentationStage(StructuredLlmStageRunner s
|
||||
|
||||
private static string BuildPrompt(VisualBriefingManifest manifest, VisualBriefingPlanArtifact plan, VisualBriefingPresentationArtifact? parent)
|
||||
{
|
||||
var parentJson = parent is null ? "none" : JsonSerializer.Serialize(new { parent.Layout, parent.Profile }, VisualBriefingJson.Compact);
|
||||
var parentJson = parent is null ? "none" : JsonSerializer.Serialize(new { parent.Layout, parent.Profile }, VisualBriefingJson.Canonical);
|
||||
return $"""
|
||||
Operation: {(parent is null ? "CREATE_DESIGN" : "CHANGE_DESIGN")}
|
||||
Design instruction: {manifest.Settings.Instruction}
|
||||
Planned sections and components:
|
||||
{JsonSerializer.Serialize(plan.Sections, VisualBriefingJson.Compact)}
|
||||
{JsonSerializer.Serialize(plan.Sections, VisualBriefingJson.Canonical)}
|
||||
Parent design:
|
||||
{parentJson}
|
||||
""";
|
||||
|
||||
@ -164,11 +164,11 @@ public sealed partial class VisualBriefingStore
|
||||
return null;
|
||||
|
||||
var hash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(artifact.Facts, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Metrics, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Tables, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.SourceCoverage, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.AssetPlan, VisualBriefingJson.Compact));
|
||||
JsonSerializer.Serialize(artifact.Facts, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Metrics, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Tables, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.SourceCoverage, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.AssetPlan, VisualBriefingJson.Canonical));
|
||||
|
||||
return string.Equals(hash, artifact.PayloadHash, StringComparison.Ordinal) ? artifact : null;
|
||||
}
|
||||
@ -217,7 +217,7 @@ public sealed partial class VisualBriefingStore
|
||||
return null;
|
||||
|
||||
var hash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(artifact.Sections, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Sections, VisualBriefingJson.Canonical),
|
||||
artifact.StructuralSignature);
|
||||
|
||||
return string.Equals(hash, artifact.PayloadHash, StringComparison.Ordinal) ? artifact : null;
|
||||
@ -273,15 +273,15 @@ public sealed partial class VisualBriefingStore
|
||||
return null;
|
||||
|
||||
var payloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(artifact.Slots, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Charts, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Controls, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Formulas, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.AccessibilityTexts, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.SourceReferences, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Slots, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Charts, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Controls, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.Formulas, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.AccessibilityTexts, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.SourceReferences, VisualBriefingJson.Canonical),
|
||||
artifact.ResetLabel,
|
||||
JsonSerializer.Serialize(artifact.SourceCoverage, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.AssetPlan, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.SourceCoverage, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(artifact.AssetPlan, VisualBriefingJson.Canonical),
|
||||
artifact.StructuralSignature);
|
||||
|
||||
return string.Equals(payloadHash, artifact.PayloadHash, StringComparison.Ordinal) ? artifact : null;
|
||||
@ -336,7 +336,7 @@ public sealed partial class VisualBriefingStore
|
||||
return null;
|
||||
|
||||
var payloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(artifact.Layout, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(artifact.Layout, VisualBriefingJson.Canonical),
|
||||
artifact.Profile.ToString(),
|
||||
artifact.TemplateHash,
|
||||
artifact.CssHash);
|
||||
|
||||
@ -504,15 +504,15 @@ public sealed partial class VisualBriefingStore
|
||||
|
||||
// Section order and count must match ReadContentArtifactAsync exactly:
|
||||
var contentHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(importedSlots, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(importedSlots, VisualBriefingJson.Canonical),
|
||||
"[]",
|
||||
"[]",
|
||||
"[]",
|
||||
"{}",
|
||||
"{}",
|
||||
"Reset",
|
||||
JsonSerializer.Serialize(coverage, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(assetPlan, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(coverage, VisualBriefingJson.Canonical),
|
||||
JsonSerializer.Serialize(assetPlan, VisualBriefingJson.Canonical),
|
||||
structuralSignature);
|
||||
|
||||
var content = new VisualBriefingContentArtifact
|
||||
@ -551,7 +551,7 @@ public sealed partial class VisualBriefingStore
|
||||
ArtifactId = Guid.NewGuid(),
|
||||
CreatedAtUtc = DateTimeOffset.UtcNow,
|
||||
PayloadHash = VisualBriefingHashing.ComputeSections(
|
||||
JsonSerializer.Serialize(importedLayout, VisualBriefingJson.Compact),
|
||||
JsonSerializer.Serialize(importedLayout, VisualBriefingJson.Canonical),
|
||||
VisualBriefingDesignProfile.EDITORIAL.ToString(),
|
||||
templateHash,
|
||||
cssHash),
|
||||
@ -607,7 +607,7 @@ public sealed partial class VisualBriefingStore
|
||||
var businessData = VisualBriefingHashing.CanonicalJson(VisualBriefingData.RemoveProtectedData(parts.Data));
|
||||
var assets = JsonSerializer.Serialize(
|
||||
VisualBriefingData.ExtractAssets(parts.Data),
|
||||
VisualBriefingJson.Compact);
|
||||
VisualBriefingJson.Canonical);
|
||||
|
||||
return new(
|
||||
VisualBriefingHashing.Compute(businessData),
|
||||
|
||||
@ -45,7 +45,7 @@ public sealed partial class VisualBriefingStore(
|
||||
private const string TRANSCRIPTS_DIRECTORY_NAME = "transcripts";
|
||||
|
||||
/// <summary>Gets the shared persistence JSON options.</summary>
|
||||
private static readonly JsonSerializerOptions JSON_OPTIONS = VisualBriefingJson.Indented;
|
||||
private static readonly JsonSerializerOptions JSON_OPTIONS = VisualBriefingJson.Persistence;
|
||||
|
||||
/// <summary>Stores per-project process locks.</summary>
|
||||
private readonly ConcurrentDictionary<Guid, SemaphoreSlim> briefingLocks = [];
|
||||
|
||||
@ -184,7 +184,7 @@ internal static partial class VisualBriefingStructuredResponseProcessor
|
||||
T? parsed;
|
||||
try
|
||||
{
|
||||
parsed = JsonSerializer.Deserialize<T>(candidate.Json, VisualBriefingJson.Compact);
|
||||
parsed = JsonSerializer.Deserialize<T>(candidate.Json, VisualBriefingJson.Canonical);
|
||||
}
|
||||
catch (JsonException exception)
|
||||
{
|
||||
|
||||
@ -685,7 +685,7 @@ internal static partial class VisualBriefingValidation
|
||||
|
||||
private static bool ContainsForbidden<T>(T value)
|
||||
{
|
||||
var json = JsonSerializer.SerializeToElement(value, VisualBriefingJson.Compact);
|
||||
var json = JsonSerializer.SerializeToElement(value, VisualBriefingJson.Canonical);
|
||||
return ContainsForbiddenElement(json);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user