mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-24 20:52:11 +00:00
Improved recompile logic to use AI Studio export pipeline
This commit is contained in:
parent
a921cd9305
commit
868a8b1cf3
@ -182,7 +182,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</MudTooltip>
|
</MudTooltip>
|
||||||
<MudTooltip Text="@(this.SelectedVersionSupportsEdits
|
<MudTooltip Text="@(this.SelectedVersionSupportsEdits
|
||||||
? T("Recompile this version with the current AI Studio compiler and runtime without model calls.")
|
? T("Recompile this version with the current AI Studio version without AI model calls.")
|
||||||
: T("This version has no compatible semantic artifacts. Rebuild the briefing instead."))">
|
: T("This version has no compatible semantic artifacts. Rebuild the briefing instead."))">
|
||||||
<span>
|
<span>
|
||||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Code" OnClick="@(() => this.RecompileAsync())" Disabled="@this.CannotRecompile">@T("Recompile briefing")</MudButton>
|
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Code" OnClick="@(() => this.RecompileAsync())" Disabled="@this.CannotRecompile">@T("Recompile briefing")</MudButton>
|
||||||
|
|||||||
@ -193,7 +193,7 @@ public partial class VisualBriefingAssistant
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Recompiles the selected immutable revision with the current compiler and runtime.
|
/// Recompiles the selected immutable revision with the current AI Studio export pipeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parentRevisionOverride">An optional parent used while resuming a persisted operation.</param>
|
/// <param name="parentRevisionOverride">An optional parent used while resuming a persisted operation.</param>
|
||||||
private async Task RecompileAsync(Guid? parentRevisionOverride = null)
|
private async Task RecompileAsync(Guid? parentRevisionOverride = null)
|
||||||
@ -234,13 +234,6 @@ public partial class VisualBriefingAssistant
|
|||||||
this.lastBuildDiagnostics = result.Diagnostics;
|
this.lastBuildDiagnostics = result.Diagnostics;
|
||||||
this.latestBuild = this.BuildProgressService.GetLatest(briefingId) ?? (await this.Store.ListBuildsAsync(briefingId, cancellation.Token)).FirstOrDefault();
|
this.latestBuild = this.BuildProgressService.GetLatest(briefingId) ?? (await this.Store.ListBuildsAsync(briefingId, cancellation.Token)).FirstOrDefault();
|
||||||
|
|
||||||
if (result.FailureCode is VisualBriefingFailureCode.NO_CHANGES)
|
|
||||||
{
|
|
||||||
this.Snackbar.Add(T("The selected briefing version already uses the current compiler and runtime."), Severity.Info);
|
|
||||||
terminalStatus = AssistantSessionStatus.COMPLETED;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!result.Success || result.Version is null)
|
if (!result.Success || result.Version is null)
|
||||||
{
|
{
|
||||||
terminalIssue = result.Issue;
|
terminalIssue = result.Issue;
|
||||||
@ -265,7 +258,7 @@ public partial class VisualBriefingAssistant
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Snackbar.Add(T("The briefing was recompiled with the current AI Studio runtime."), Severity.Success);
|
this.Snackbar.Add(T("The briefing was recompiled with the current AI Studio version."), Severity.Success);
|
||||||
terminalStatus = AssistantSessionStatus.COMPLETED;
|
terminalStatus = AssistantSessionStatus.COMPLETED;
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
|
|||||||
@ -5,8 +5,8 @@ namespace AIStudio.Assistants.VisualBriefing;
|
|||||||
internal sealed partial class VisualBriefingBuildOrchestrator
|
internal sealed partial class VisualBriefingBuildOrchestrator
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Recompiles one immutable revision with the current deterministic compiler and standalone
|
/// Recompiles one immutable revision with the current deterministic export pipeline without
|
||||||
/// runtime without accessing sources or calling a model.
|
/// accessing sources or calling a model.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="manifest">The current local briefing manifest.</param>
|
/// <param name="manifest">The current local briefing manifest.</param>
|
||||||
/// <param name="parentRevisionId">The revision whose semantic artifacts are reused.</param>
|
/// <param name="parentRevisionId">The revision whose semantic artifacts are reused.</param>
|
||||||
@ -144,6 +144,8 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
|||||||
compiled.TemplateHtml, compiled.Css,
|
compiled.TemplateHtml, compiled.Css,
|
||||||
content.Charts.Count > 0));
|
content.Charts.Count > 0));
|
||||||
|
|
||||||
|
var contributions = await this.ResolveRecompileModelContributionsAsync(manifest.BriefingId, parentVersion, evidence, plan, content, previousPresentation, token);
|
||||||
|
var presentationModel = contributions.First(contribution => contribution.Role is VisualBriefingModelRole.DESIGN).Model;
|
||||||
var presentation = new VisualBriefingPresentationArtifact
|
var presentation = new VisualBriefingPresentationArtifact
|
||||||
{
|
{
|
||||||
ArtifactId = Guid.NewGuid(),
|
ArtifactId = Guid.NewGuid(),
|
||||||
@ -160,7 +162,7 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
|||||||
Css = compiled.Css,
|
Css = compiled.Css,
|
||||||
TemplateHash = compiled.TemplateHash,
|
TemplateHash = compiled.TemplateHash,
|
||||||
CssHash = compiled.CssHash,
|
CssHash = compiled.CssHash,
|
||||||
Model = previousPresentation.Model,
|
Model = presentationModel,
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.store.WritePresentationArtifactAsync(manifest.BriefingId, presentation, token);
|
await this.store.WritePresentationArtifactAsync(manifest.BriefingId, presentation, token);
|
||||||
@ -204,7 +206,6 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
|||||||
await this.store.SaveBuildAsync(build, token);
|
await this.store.SaveBuildAsync(build, token);
|
||||||
this.progressService.Publish(build);
|
this.progressService.Publish(build);
|
||||||
|
|
||||||
var contributions = parentVersion.ModelContributions.ToList();
|
|
||||||
var revision = await this.store.AddRevisionAsync(new(
|
var revision = await this.store.AddRevisionAsync(new(
|
||||||
manifest.BriefingId,
|
manifest.BriefingId,
|
||||||
parentRevisionId,
|
parentRevisionId,
|
||||||
@ -230,35 +231,7 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
|||||||
|
|
||||||
var commitStage = GetStage(build, VisualBriefingBuildStage.COMMIT);
|
var commitStage = GetStage(build, VisualBriefingBuildStage.COMMIT);
|
||||||
if (!revision.Success || revision.Version is null)
|
if (!revision.Success || revision.Version is null)
|
||||||
{
|
throw new VisualBriefingBuildException(VisualBriefingFailureCode.STORE_FAILED, VisualBriefingBuildStage.COMMIT, revision.Issue, "The immutable recompiled revision commit was rejected.");
|
||||||
if (revision.Issue.Contains("did not change", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
assemblyStage.Status = VisualBriefingBuildStageStatus.COMPLETED;
|
|
||||||
assemblyStage.FinishedAtUtc = DateTimeOffset.UtcNow;
|
|
||||||
assemblyStage.OutputHash = parentVersion.PayloadHash;
|
|
||||||
MarkSkipped(build, VisualBriefingBuildStage.COMMIT, parentVersion.PayloadHash);
|
|
||||||
build.Status = VisualBriefingBuildStatus.COMPLETED;
|
|
||||||
build.Failure = null;
|
|
||||||
build.UpdatedAtUtc = DateTimeOffset.UtcNow;
|
|
||||||
await this.store.SaveBuildAsync(build, token);
|
|
||||||
this.progressService.Publish(build);
|
|
||||||
diagnostics.FailureCode = VisualBriefingFailureCode.NO_CHANGES;
|
|
||||||
diagnostics.FinishedAtUtc = DateTimeOffset.UtcNow;
|
|
||||||
return new(
|
|
||||||
false,
|
|
||||||
null,
|
|
||||||
"The selected briefing version already uses the current compiler and runtime.",
|
|
||||||
VisualBriefingFailureCode.NO_CHANGES,
|
|
||||||
diagnostics,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new VisualBriefingBuildException(
|
|
||||||
VisualBriefingFailureCode.STORE_FAILED,
|
|
||||||
VisualBriefingBuildStage.COMMIT,
|
|
||||||
revision.Issue,
|
|
||||||
"The immutable recompiled revision commit was rejected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
assemblyStage.Status = VisualBriefingBuildStageStatus.COMPLETED;
|
assemblyStage.Status = VisualBriefingBuildStageStatus.COMPLETED;
|
||||||
assemblyStage.FinishedAtUtc = DateTimeOffset.UtcNow;
|
assemblyStage.FinishedAtUtc = DateTimeOffset.UtcNow;
|
||||||
@ -341,4 +314,77 @@ internal sealed partial class VisualBriefingBuildOrchestrator
|
|||||||
gate.Release();
|
gate.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reconstructs the most specific model attribution available for each reused semantic artifact.
|
||||||
|
/// </summary>
|
||||||
|
private async Task<List<VisualBriefingModelContribution>> ResolveRecompileModelContributionsAsync(Guid briefingId, VisualBriefingVersion parentVersion,
|
||||||
|
VisualBriefingEvidenceArtifact evidence, VisualBriefingPlanArtifact plan, VisualBriefingContentArtifact content, VisualBriefingPresentationArtifact presentation,
|
||||||
|
CancellationToken token)
|
||||||
|
{
|
||||||
|
var builds = await this.store.ListBuildsAsync(briefingId, token);
|
||||||
|
|
||||||
|
return
|
||||||
|
[
|
||||||
|
new(
|
||||||
|
VisualBriefingModelRole.EVIDENCE,
|
||||||
|
ResolveRecompileModelLabel(
|
||||||
|
builds,
|
||||||
|
build => build.EvidenceArtifactId,
|
||||||
|
evidence.ArtifactId,
|
||||||
|
VisualBriefingBuildStage.EVIDENCE,
|
||||||
|
ExistingModelLabel(parentVersion, VisualBriefingModelRole.EVIDENCE, evidence.Model))),
|
||||||
|
|
||||||
|
new(
|
||||||
|
VisualBriefingModelRole.PLAN,
|
||||||
|
ResolveRecompileModelLabel(
|
||||||
|
builds,
|
||||||
|
build => build.PlanArtifactId,
|
||||||
|
plan.ArtifactId,
|
||||||
|
VisualBriefingBuildStage.PLAN,
|
||||||
|
ExistingModelLabel(parentVersion, VisualBriefingModelRole.PLAN, plan.Model))),
|
||||||
|
|
||||||
|
new(
|
||||||
|
VisualBriefingModelRole.CONTENT,
|
||||||
|
ResolveRecompileModelLabel(
|
||||||
|
builds,
|
||||||
|
build => build.ContentArtifactId,
|
||||||
|
content.ArtifactId,
|
||||||
|
VisualBriefingBuildStage.CONTENT,
|
||||||
|
ExistingModelLabel(parentVersion, VisualBriefingModelRole.CONTENT, content.Model))),
|
||||||
|
|
||||||
|
new(
|
||||||
|
VisualBriefingModelRole.DESIGN,
|
||||||
|
ResolveRecompileModelLabel(
|
||||||
|
builds,
|
||||||
|
build => build.PresentationArtifactId,
|
||||||
|
presentation.ArtifactId,
|
||||||
|
VisualBriefingBuildStage.DESIGN,
|
||||||
|
ExistingModelLabel(parentVersion, VisualBriefingModelRole.DESIGN, presentation.Model))),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resolves the provider and model that originally produced one immutable artifact.
|
||||||
|
/// </summary>
|
||||||
|
private static string ResolveRecompileModelLabel(IReadOnlyList<VisualBriefingBuildRecord> builds, Func<VisualBriefingBuildRecord, Guid?> artifactId,
|
||||||
|
Guid expectedArtifactId, VisualBriefingBuildStage stage, string fallback)
|
||||||
|
{
|
||||||
|
var producingBuild = builds.FirstOrDefault(build =>
|
||||||
|
artifactId(build) == expectedArtifactId &&
|
||||||
|
!string.IsNullOrWhiteSpace(build.ProviderFamily) &&
|
||||||
|
!string.IsNullOrWhiteSpace(build.Model) &&
|
||||||
|
build.Stages.Any(candidate => candidate.Stage == stage && candidate.Status is VisualBriefingBuildStageStatus.COMPLETED));
|
||||||
|
|
||||||
|
return producingBuild is null ? fallback : VisualBriefingModelNames.ExportLabel(producingBuild.ProviderFamily, producingBuild.Model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the persisted role attribution, falling back to the immutable artifact label.
|
||||||
|
/// </summary>
|
||||||
|
private static string ExistingModelLabel(VisualBriefingVersion parentVersion, VisualBriefingModelRole role, string artifactModel)
|
||||||
|
{
|
||||||
|
var contribution = parentVersion.ModelContributions.FirstOrDefault(candidate => candidate.Role == role && !string.IsNullOrWhiteSpace(candidate.Model));
|
||||||
|
return contribution?.Model ?? artifactModel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +86,8 @@ public sealed partial class VisualBriefingStore
|
|||||||
!string.Equals(parent.AssetHash, hashes.AssetHash, StringComparison.Ordinal)))
|
!string.Equals(parent.AssetHash, hashes.AssetHash, StringComparison.Ordinal)))
|
||||||
return VisualBriefingRevisionResult.Failure("A recompile attempted to modify semantic artifacts or embedded assets.");
|
return VisualBriefingRevisionResult.Failure("A recompile attempted to modify semantic artifacts or embedded assets.");
|
||||||
|
|
||||||
if (string.Equals(parent.DataHash, hashes.DataHash, StringComparison.Ordinal) &&
|
if (request.EditMode is not VisualBriefingEditMode.RECOMPILE &&
|
||||||
|
string.Equals(parent.DataHash, hashes.DataHash, StringComparison.Ordinal) &&
|
||||||
string.Equals(parent.AssetHash, hashes.AssetHash, StringComparison.Ordinal) &&
|
string.Equals(parent.AssetHash, hashes.AssetHash, StringComparison.Ordinal) &&
|
||||||
string.Equals(parent.TemplateHash, hashes.TemplateHash, StringComparison.Ordinal) &&
|
string.Equals(parent.TemplateHash, hashes.TemplateHash, StringComparison.Ordinal) &&
|
||||||
string.Equals(parent.CssHash, hashes.CssHash, StringComparison.Ordinal) &&
|
string.Equals(parent.CssHash, hashes.CssHash, StringComparison.Ordinal) &&
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user