@model StoryIntelligenceSavedRunDetailViewModel @{ ViewData["Title"] = "Story Intelligence Run"; var run = Model.Run; }

Admin utility

Story Intelligence Run @(run is null ? string.Empty : run.StoryIntelligenceRunID.ToString("N0"))

Saved audit output from the admin chapter-to-scene dry-run pipeline.

@if (TempData["AdminMessage"] is string message) {
@message
} @if (run is null) {

This Story Intelligence run could not be found.

} else {

Run metadata

Status

@run.Status

Scenes

@Model.SceneResults.Count.ToString("N0")

Tokens

@Display(run.TotalTokens)

Duration

@DisplayDuration(run.TotalDurationMs)

Source type
@run.SourceType
Source file
@Display(run.SourceFileName)
Source file size
@DisplayBytes(run.SourceFileSizeBytes)
Source word count
@Display(run.SourceWordCount)
Source character count
@Display(run.SourceCharacterCount)
Source chapter count
@Display(run.SourceChapterCount)
Detected document features
Images: @Display(run.SourceDetectedImagesCount), tables: @Display(run.SourceDetectedTablesCount), footnotes: @Display(run.SourceDetectedFootnotesCount), comments: @Display(run.SourceDetectedCommentsCount)
Project
@DisplayName(run.ProjectTitle, run.ProjectID, "Project")
Book
@DisplayName(run.BookTitle, run.BookID, "Book")
Prompt version
@run.PromptVersion
Prompt versions summary
@Display(run.PromptVersionsSummary)
Model
@run.Model
Started
@run.StartedUtc.ToString("yyyy-MM-dd HH:mm:ss") UTC
Completed
@(run.CompletedUtc?.ToString("yyyy-MM-dd HH:mm:ss") ?? "None") UTC
Failure stage
@Display(run.FailureStage)
Input tokens
@Display(run.TotalInputTokens)
Output tokens
@Display(run.TotalOutputTokens)
Estimated cost
@DisplayCost(run.EstimatedCostGBP, "GBP") / @DisplayCost(run.EstimatedCostUSD, "USD")
Error message
@Display(run.ErrorMessage)
Error detail
@Display(run.ErrorDetail)

Chapter result

@if (Model.ChapterResult is null) {

No chapter result was saved for this run.

} else { var chapter = Model.ChapterResult;
Source label
@chapter.SourceLabel
Chapter
@Display(chapter.ChapterNumber)
Prompt version
@chapter.PromptVersion
Validation
@chapter.ValidationErrorsCount.ToString("N0") error(s), @chapter.ValidationWarningsCount.ToString("N0") warning(s)
Duration
@DisplayDuration(chapter.DurationMs)
Tokens
@Display(chapter.TotalTokens) total (@Display(chapter.InputTokens) input, @Display(chapter.OutputTokens) output)
}

Scene results

@if (Model.SceneResults.Count == 0) {

No scene results were saved for this run.

}
@foreach (var scene in Model.SceneResults) {

Suggested Scene @scene.TemporarySceneNumber.ToString("N0")

Paragraph range
@Display(scene.StartParagraph)-@Display(scene.EndParagraph)
Source label
@scene.SourceLabel
Prompt version
@scene.PromptVersion
Validation
@scene.ValidationErrorsCount.ToString("N0") error(s), @scene.ValidationWarningsCount.ToString("N0") warning(s)
Duration
@DisplayDuration(scene.DurationMs)
Tokens
@Display(scene.TotalTokens) total (@Display(scene.InputTokens) input, @Display(scene.OutputTokens) output)
} } @functions { private static string Display(object? value) => value switch { null => "None", string text when string.IsNullOrWhiteSpace(text) => "None", decimal number => number.ToString("0.##"), int number => number.ToString("N0"), _ => value.ToString() ?? "None" }; private static string DisplayDuration(long? milliseconds) => milliseconds.HasValue ? TimeSpan.FromMilliseconds(milliseconds.Value).TotalSeconds < 1 ? $"{milliseconds.Value:N0} ms" : $"{TimeSpan.FromMilliseconds(milliseconds.Value).TotalSeconds:0.00} sec" : "None"; private static string DisplayBytes(long? bytes) => bytes.HasValue ? $"{bytes.Value:N0} bytes" : "None"; private static string DisplayCost(decimal? value, string currency) => value.HasValue ? $"{value.Value:0.000000} {currency}" : "None"; private static string DisplayName(string? title, int? id, string label) => !string.IsNullOrWhiteSpace(title) ? title : id.HasValue ? $"{label} {id.Value:N0}" : "None"; }