mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-18 02:57:59 +00:00
Rework of the file export (#894)
Co-authored-by: Thorsten Sommer <SommerEngineering@users.noreply.github.com>
This commit is contained in:
1 parent
f14c69b938
commit
c66a61713d
33 files changed
+1212
-266
No files matched your search
@@ -75,9 +75,9 @@
|
||||
<div id="@BEFORE_RESULT_DIV_ID" class="mt-3">
|
||||
</div>
|
||||
|
||||
@if (this.ShowResult && !this.ShowEntireChatThread && this.ResultingContentBlock is not null && this.ResultingContentBlock.Content is not null)
|
||||
@if (this.ShowResult && !this.ShowEntireChatThread && this.ResultingContentBlock?.Content != null)
|
||||
{
|
||||
<ContentBlockComponent Role="@(this.ResultingContentBlock.Role)" Type="@(this.ResultingContentBlock.ContentType)" Time="@(this.ResultingContentBlock.Time)" Content="@this.ResultingContentBlock.Content"/>
|
||||
<ContentBlockComponent Role="@(this.ResultingContentBlock.Role)" Type="@(this.ResultingContentBlock.ContentType)" Time="@(this.ResultingContentBlock.Time)" Content="@this.ResultingContentBlock.Content" ExportTitle="@TB("Export result")"/>
|
||||
}
|
||||
|
||||
@if(this.ShowResult && this.ShowEntireChatThread && this.ChatThread is not null)
|
||||
@@ -86,7 +86,7 @@
|
||||
{
|
||||
@if (block is { HideFromUser: false, Content: not null })
|
||||
{
|
||||
<ContentBlockComponent Role="@block.Role" Type="@block.ContentType" Time="@block.Time" Content="@block.Content"/>
|
||||
<ContentBlockComponent Role="@block.Role" Type="@block.ContentType" Time="@block.Time" Content="@block.Content" ExportTitle="@TB("Export result")"/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,10 +115,19 @@ else
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
@if (this.outputMode is BatchProcessingOutputMode.MARKDOWN_FILES)
|
||||
@if (this.outputMode is BatchProcessingOutputMode.INDIVIDUAL_FILES)
|
||||
{
|
||||
<MudSelect T="FileExportFormat" @bind-Value="@this.resultFileFormat" Disabled="@this.isProcessingBatch" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Label="@T("File format")" HelperText="@T("Choose the format of the result files. Everything except Markdown is converted by Pandoc, which AI Studio offers to install when it is missing.")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
|
||||
@foreach (var format in FileExportFormatExtensions.ANSWER_FORMATS)
|
||||
{
|
||||
<MudSelectItem Value="@format">
|
||||
@format.ToName()
|
||||
</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
|
||||
<MudJustifiedText Typo="Typo.body2" Class="mb-3">
|
||||
@T("Each answer is stored as its own Markdown file. Those files are named after the document, e.g., the answer for report.pdf is stored as report_result.md.")
|
||||
@(string.Format(T("Each answer is stored as its own file. Those files are named after the document, e.g., the answer for report.pdf is stored as report_result{0}."), this.resultFileFormat.ToFileExtension()))
|
||||
</MudJustifiedText>
|
||||
}
|
||||
else
|
||||
|
||||
+10
-9
@@ -71,8 +71,8 @@ public partial class AssistantBatchProcessing
|
||||
/// <summary>
|
||||
/// Checks whether a document can be restored from the previous run. Beyond
|
||||
/// the log entry, the result of the previous run must still exist: in the
|
||||
/// table mode the answer within the results table, in the Markdown mode the
|
||||
/// result file. Without the result, restoring would mark the document as
|
||||
/// table mode the answer within the results table, in the individual file
|
||||
/// mode the result file. Without the result, restoring would mark the document as
|
||||
/// done while its answer is lost, so we process it again instead.
|
||||
/// </summary>
|
||||
private bool CanRestoreFromPreviousRun(string relativePath, string resolvedOutputDirectory, Dictionary<string, BatchProcessingLogEntry> previousLog, Dictionary<string, string> previousResults, out BatchProcessingLogEntry? logEntry)
|
||||
@@ -106,9 +106,9 @@ public partial class AssistantBatchProcessing
|
||||
private async Task WriteLogAsync(string resolvedOutputDirectory)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(BatchProcessingCsv.ToCsvRow(LOG_SEPARATOR, T("File"), T("Time"), T("Model"), T("Status"), T("Details")));
|
||||
sb.AppendLine(CsvWriter.ToRow(LOG_SEPARATOR, T("File"), T("Time"), T("Model"), T("Status"), T("Details")));
|
||||
foreach (var fileResult in this.fileResults.Where(x => x.Status is not BatchProcessingFileStatus.QUEUED and not BatchProcessingFileStatus.PROCESSING))
|
||||
sb.AppendLine(BatchProcessingCsv.ToCsvRow(LOG_SEPARATOR, fileResult.RelativePath, fileResult.ProcessedAt.ToString(TIME_FORMAT, CultureInfo.InvariantCulture), fileResult.ModelName, fileResult.Status.ToString(), fileResult.Message));
|
||||
sb.AppendLine(CsvWriter.ToRow(LOG_SEPARATOR, fileResult.RelativePath, fileResult.ProcessedAt.ToString(TIME_FORMAT, CultureInfo.InvariantCulture), fileResult.ModelName, fileResult.Status.ToString(), fileResult.Message));
|
||||
|
||||
await this.WriteCsvFileAsync(Path.Join(resolvedOutputDirectory, LOG_FILENAME), sb.ToString());
|
||||
}
|
||||
@@ -120,9 +120,9 @@ public partial class AssistantBatchProcessing
|
||||
{
|
||||
var separator = this.csvSeparator.Character(this.customCsvSeparator);
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine(BatchProcessingCsv.ToCsvRow(separator, T("File"), this.ResultColumnHeader));
|
||||
sb.AppendLine(CsvWriter.ToRow(separator, T("File"), this.ResultColumnHeader));
|
||||
foreach (var fileResult in this.fileResults.Where(x => x.Status is BatchProcessingFileStatus.DONE))
|
||||
sb.AppendLine(BatchProcessingCsv.ToCsvRow(separator, fileResult.RelativePath, fileResult.ResultText));
|
||||
sb.AppendLine(CsvWriter.ToRow(separator, fileResult.RelativePath, fileResult.ResultText));
|
||||
|
||||
await this.WriteCsvFileAsync(Path.Join(resolvedOutputDirectory, this.ResolveResultsFileName()), sb.ToString());
|
||||
}
|
||||
@@ -232,7 +232,7 @@ public partial class AssistantBatchProcessing
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the name of the Markdown result file for one document.
|
||||
/// Creates the name of the result file for one document, in the chosen file format.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Two documents of the same run may share their name and differ only in
|
||||
@@ -242,13 +242,14 @@ public partial class AssistantBatchProcessing
|
||||
/// </remarks>
|
||||
private string CreateResultFileName(string sourceFileName)
|
||||
{
|
||||
var extension = this.resultFileFormat.ToFileExtension();
|
||||
var stem = Path.GetFileNameWithoutExtension(sourceFileName);
|
||||
var candidate = $"{stem}{RESULT_FILE_SUFFIX}";
|
||||
var candidate = $"{stem}{RESULT_FILE_SUFFIX}{extension}";
|
||||
|
||||
var counter = 2;
|
||||
while (!this.usedResultFileNames.Add(candidate))
|
||||
{
|
||||
candidate = $"{stem}_result_{counter}.md";
|
||||
candidate = $"{stem}{RESULT_FILE_SUFFIX}_{counter}{extension}";
|
||||
counter++;
|
||||
}
|
||||
|
||||
|
||||
+30
-4
@@ -1,6 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace AIStudio.Assistants.BatchProcessing;
|
||||
|
||||
@@ -14,6 +13,19 @@ public partial class AssistantBatchProcessing
|
||||
|
||||
var (resolvedOutputDirectory, files) = runPreparation.Value;
|
||||
|
||||
//
|
||||
// Every format but Markdown is written by Pandoc, so it has to be there before the first
|
||||
// document. Asking per document would put the installation dialog in front of the user
|
||||
// hundreds of times, and starting without it would spend time and tokens on answers we
|
||||
// cannot write anywhere:
|
||||
//
|
||||
if (this.outputMode is BatchProcessingOutputMode.INDIVIDUAL_FILES && this.resultFileFormat.UsesPandoc())
|
||||
{
|
||||
var pandocState = await this.PandocAvailability.EnsureAvailabilityAsync(showSuccessMessage: false, showDialog: true);
|
||||
if (!pandocState.IsAvailable)
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// When the output folder already contains a log, a previous run was
|
||||
// interrupted or produced errors. Let the user decide what to do:
|
||||
@@ -63,7 +75,7 @@ public partial class AssistantBatchProcessing
|
||||
if (DateTimeOffset.TryParseExact(logEntry.Time, TIME_FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var processedAt))
|
||||
fileResult.ProcessedAt = processedAt;
|
||||
|
||||
// Reserve the Markdown file name of the previous run, so that a
|
||||
// Reserve the result file name of the previous run, so that a
|
||||
// document processed now cannot overwrite that earlier result:
|
||||
if (!string.IsNullOrWhiteSpace(logEntry.Details))
|
||||
this.usedResultFileNames.Add(logEntry.Details);
|
||||
@@ -211,12 +223,26 @@ public partial class AssistantBatchProcessing
|
||||
}
|
||||
|
||||
fileResult.ResultText = aiAnswer;
|
||||
if (this.outputMode is BatchProcessingOutputMode.MARKDOWN_FILES)
|
||||
if (this.outputMode is BatchProcessingOutputMode.INDIVIDUAL_FILES)
|
||||
{
|
||||
try
|
||||
{
|
||||
var resultFilePath = Path.Join(resolvedOutputDirectory, this.CreateResultFileName(fileResult.FileName));
|
||||
await File.WriteAllTextAsync(resultFilePath, aiAnswer, Encoding.UTF8, CancellationToken.None);
|
||||
if (this.resultFileFormat.UsesPandoc())
|
||||
{
|
||||
//
|
||||
// Pandoc reports a failure instead of throwing, because one document which
|
||||
// cannot be converted must not end a run over hundreds of them:
|
||||
//
|
||||
if (!await PandocExport.ConvertAsync(this.RustService, aiAnswer, resultFilePath, this.resultFileFormat, token))
|
||||
{
|
||||
this.FinishFileResult(fileResult, BatchProcessingFileStatus.FAILED, T("Was not able to convert the answer into the chosen file format."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
await File.WriteAllTextAsync(resultFilePath, aiAnswer, this.resultFileFormat.ToFileEncoding(), CancellationToken.None);
|
||||
|
||||
this.FinishFileResult(fileResult, BatchProcessingFileStatus.DONE, Path.GetFileName(resultFilePath));
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
+3
@@ -16,6 +16,7 @@ public partial class AssistantBatchProcessing
|
||||
private static readonly AssistantSessionStateKey<string> PROMPT_FILE_LOAD_ISSUE_STATE_KEY = new(nameof(promptFileLoadIssue));
|
||||
private static readonly AssistantSessionStateKey<DataDocumentAnalysisPolicy?> SELECTED_POLICY_STATE_KEY = new(nameof(selectedPolicy));
|
||||
private static readonly AssistantSessionStateKey<BatchProcessingOutputMode> OUTPUT_MODE_STATE_KEY = new(nameof(outputMode));
|
||||
private static readonly AssistantSessionStateKey<FileExportFormat> RESULT_FILE_FORMAT_STATE_KEY = new(nameof(resultFileFormat));
|
||||
private static readonly AssistantSessionStateKey<string> RESULT_COLUMN_HEADER_STATE_KEY = new(nameof(resultColumnHeader));
|
||||
private static readonly AssistantSessionStateKey<string> CSV_FILE_NAME_STATE_KEY = new(nameof(csvFileName));
|
||||
private static readonly AssistantSessionStateKey<BatchProcessingCsvSeparator> CSV_SEPARATOR_STATE_KEY = new(nameof(csvSeparator));
|
||||
@@ -43,6 +44,7 @@ public partial class AssistantBatchProcessing
|
||||
state.Set(PROMPT_FILE_LOAD_ISSUE_STATE_KEY, this.promptFileLoadIssue);
|
||||
state.Set(SELECTED_POLICY_STATE_KEY, this.selectedPolicy);
|
||||
state.Set(OUTPUT_MODE_STATE_KEY, this.outputMode);
|
||||
state.Set(RESULT_FILE_FORMAT_STATE_KEY, this.resultFileFormat);
|
||||
state.Set(RESULT_COLUMN_HEADER_STATE_KEY, this.resultColumnHeader);
|
||||
state.Set(CSV_FILE_NAME_STATE_KEY, this.csvFileName);
|
||||
state.Set(CSV_SEPARATOR_STATE_KEY, this.csvSeparator);
|
||||
@@ -71,6 +73,7 @@ public partial class AssistantBatchProcessing
|
||||
state.Restore(PROMPT_FILE_LOAD_ISSUE_STATE_KEY, value => this.promptFileLoadIssue = value);
|
||||
state.Restore(SELECTED_POLICY_STATE_KEY, value => this.selectedPolicy = value);
|
||||
state.Restore(OUTPUT_MODE_STATE_KEY, value => this.outputMode = value);
|
||||
state.Restore(RESULT_FILE_FORMAT_STATE_KEY, value => this.resultFileFormat = value);
|
||||
state.Restore(RESULT_COLUMN_HEADER_STATE_KEY, value => this.resultColumnHeader = value);
|
||||
state.Restore(CSV_FILE_NAME_STATE_KEY, value => this.csvFileName = value);
|
||||
state.Restore(CSV_SEPARATOR_STATE_KEY, value => this.csvSeparator = value);
|
||||
|
||||
+10
-3
@@ -1,6 +1,7 @@
|
||||
using AIStudio.Dialogs.Settings;
|
||||
using AIStudio.Provider;
|
||||
using AIStudio.Settings.DataModel;
|
||||
using AIStudio.Tools.Services;
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
@@ -11,10 +12,13 @@ public partial class AssistantBatchProcessing : AssistantBaseCore<SettingsDialog
|
||||
[Inject]
|
||||
private IDialogService DialogService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private PandocAvailabilityService PandocAvailability { get; init; } = null!;
|
||||
|
||||
private const string DEFAULT_OUTPUT_DIRECTORY_NAME = "ai-results";
|
||||
private const string DEFAULT_RESULTS_FILENAME = "batch-results.csv";
|
||||
private const string CSV_EXTENSION = ".csv";
|
||||
private const string RESULT_FILE_SUFFIX = "_result.md";
|
||||
private const string RESULT_FILE_SUFFIX = "_result";
|
||||
private const string TRANSCRIPT_FILE_SUFFIX = ".transcript.md";
|
||||
private const string TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||
private const char LOG_SEPARATOR = ';';
|
||||
@@ -87,7 +91,8 @@ public partial class AssistantBatchProcessing : AssistantBaseCore<SettingsDialog
|
||||
private string promptFilePath = string.Empty;
|
||||
private string promptFileLoadIssue = string.Empty;
|
||||
private DataDocumentAnalysisPolicy? selectedPolicy;
|
||||
private BatchProcessingOutputMode outputMode = BatchProcessingOutputMode.MARKDOWN_FILES;
|
||||
private BatchProcessingOutputMode outputMode = BatchProcessingOutputMode.INDIVIDUAL_FILES;
|
||||
private FileExportFormat resultFileFormat = FileExportFormat.MARKDOWN;
|
||||
private string resultColumnHeader = string.Empty;
|
||||
private string csvFileName = string.Empty;
|
||||
private BatchProcessingCsvSeparator csvSeparator = BatchProcessingCsvSeparator.SEMICOLON;
|
||||
@@ -160,7 +165,8 @@ public partial class AssistantBatchProcessing : AssistantBaseCore<SettingsDialog
|
||||
this.freePrompt = string.Empty;
|
||||
this.promptFilePath = string.Empty;
|
||||
this.selectedPolicy = null;
|
||||
this.outputMode = BatchProcessingOutputMode.MARKDOWN_FILES;
|
||||
this.outputMode = BatchProcessingOutputMode.INDIVIDUAL_FILES;
|
||||
this.resultFileFormat = FileExportFormat.MARKDOWN;
|
||||
this.resultColumnHeader = string.Empty;
|
||||
this.csvFileName = string.Empty;
|
||||
this.csvSeparator = BatchProcessingCsvSeparator.SEMICOLON;
|
||||
@@ -180,6 +186,7 @@ public partial class AssistantBatchProcessing : AssistantBaseCore<SettingsDialog
|
||||
this.selectedPolicy = this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies
|
||||
.FirstOrDefault(policy => policy.Id == settings.PreselectedPolicyId);
|
||||
this.outputMode = settings.OutputMode;
|
||||
this.resultFileFormat = settings.ResultFileFormat;
|
||||
this.resultColumnHeader = settings.ResultColumnHeader;
|
||||
this.csvFileName = settings.CsvFileName;
|
||||
this.csvSeparator = settings.CsvSeparator;
|
||||
|
||||
@@ -3,35 +3,13 @@ using System.Text;
|
||||
namespace AIStudio.Assistants.BatchProcessing;
|
||||
|
||||
/// <summary>
|
||||
/// Reads and writes the CSV files of the batch processing assistant. Fields
|
||||
/// are quoted according to RFC 4180 using the separator selected for the
|
||||
/// respective file.
|
||||
/// Reads the CSV files of the batch processing assistant. Writing them is the job of CsvWriter,
|
||||
/// which quotes fields according to RFC 4180 using the separator selected for the respective file.
|
||||
/// </summary>
|
||||
public static class BatchProcessingCsv
|
||||
{
|
||||
public static string ToCsvRow(char separator, params string[] fields) => string.Join(separator, fields.Select(field => ToCsvField(field, separator)));
|
||||
|
||||
/// <summary>
|
||||
/// Quotes one CSV field according to RFC 4180.
|
||||
/// </summary>
|
||||
private static string ToCsvField(string text, char separator)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return string.Empty;
|
||||
|
||||
// Quoting the complete field is important for long and multi-line AI
|
||||
// answers: neither separators nor line breaks within an answer may
|
||||
// create another column or row.
|
||||
if (!text.Contains(separator) && !text.Contains('"') && !text.Contains('\n') && !text.Contains('\r'))
|
||||
return text;
|
||||
|
||||
return $"""
|
||||
"{text.Replace("\"", "\"\"")}"
|
||||
""";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses a CSV text which was written by <see cref="ToCsvRow"/>.
|
||||
/// Parses a CSV text which was written by CsvWriter.ToRow.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We parse the file ourselves instead of splitting lines, because quoted
|
||||
|
||||
@@ -6,9 +6,14 @@ namespace AIStudio.Assistants.BatchProcessing;
|
||||
public enum BatchProcessingOutputMode
|
||||
{
|
||||
/// <summary>
|
||||
/// One Markdown result file per processed document.
|
||||
/// One result file per processed document, written in the chosen file format.
|
||||
/// </summary>
|
||||
MARKDOWN_FILES,
|
||||
/// <remarks>
|
||||
/// This must stay the first member. Enums are persisted under their name, and an unknown name
|
||||
/// falls back to the default value of the enum, which is the member with the value zero. That
|
||||
/// is what lets settings written before this member was renamed still land here.
|
||||
/// </remarks>
|
||||
INDIVIDUAL_FILES,
|
||||
|
||||
/// <summary>
|
||||
/// A CSV results table, where each AI answer becomes one row. The content of
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ public static class BatchProcessingOutputModeExtensions
|
||||
|
||||
public static string Name(this BatchProcessingOutputMode outputMode) => outputMode switch
|
||||
{
|
||||
BatchProcessingOutputMode.MARKDOWN_FILES => TB("One Markdown file per document"),
|
||||
BatchProcessingOutputMode.INDIVIDUAL_FILES => TB("One file per document"),
|
||||
BatchProcessingOutputMode.TABLE_ONLY => TB("One CSV results table, where each answer becomes one row"),
|
||||
|
||||
_ => TB("Unknown output mode"),
|
||||
|
||||
@@ -316,6 +316,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1809312323"] = "Please se
|
||||
-- The assistant failed. The message is: '{0}'
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1833836281"] = "The assistant failed. The message is: '{0}'"
|
||||
|
||||
-- Export result
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T1840311560"] = "Export result"
|
||||
|
||||
-- The media transcription was canceled.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::ASSISTANTBASE::T241403726"] = "The media transcription was canceled."
|
||||
|
||||
@@ -379,6 +382,9 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING
|
||||
-- Failed
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T1434043348"] = "Failed"
|
||||
|
||||
-- Choose the format of the result files. Everything except Markdown is converted by Pandoc, which AI Studio offers to install when it is missing.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T1457759640"] = "Choose the format of the result files. Everything except Markdown is converted by Pandoc, which AI Studio offers to install when it is missing."
|
||||
|
||||
-- Please select the file which contains your instructions.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T1462027716"] = "Please select the file which contains your instructions."
|
||||
|
||||
@@ -496,15 +502,15 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING
|
||||
-- Was not able to read the log of the previous run. Continuing the run would process all documents again.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T2717277840"] = "Was not able to read the log of the previous run. Continuing the run would process all documents again."
|
||||
|
||||
-- Each answer is stored as its own Markdown file. Those files are named after the document, e.g., the answer for report.pdf is stored as report_result.md.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T2724126639"] = "Each answer is stored as its own Markdown file. Those files are named after the document, e.g., the answer for report.pdf is stored as report_result.md."
|
||||
|
||||
-- Before the next file starts, AI Studio waits for a random number of whole seconds from this interval. The minimum is always 6 seconds and the maximum is 300 seconds (5 minutes). Restored files and the end of a run do not add another pause.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T2742154256"] = "Before the next file starts, AI Studio waits for a random number of whole seconds from this interval. The minimum is always 6 seconds and the maximum is 300 seconds (5 minutes). Restored files and the end of a run do not add another pause."
|
||||
|
||||
-- Please enter exactly one punctuation or symbol character. Letters, numbers, spaces, quotation marks, and line breaks cannot be used as CSV separators.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T2908365499"] = "Please enter exactly one punctuation or symbol character. Letters, numbers, spaces, quotation marks, and line breaks cannot be used as CSV separators."
|
||||
|
||||
-- Was not able to convert the answer into the chosen file format.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T2949919602"] = "Was not able to convert the answer into the chosen file format."
|
||||
|
||||
-- Was not able to write the result file: {0}
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T2991295581"] = "Was not able to write the result file: {0}"
|
||||
|
||||
@@ -583,9 +589,15 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING
|
||||
-- The configured instructions file could not be read.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T4274794480"] = "The configured instructions file could not be read."
|
||||
|
||||
-- Each answer is stored as its own file. Those files are named after the document, e.g., the answer for report.pdf is stored as report_result{0}.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T428878781"] = "Each answer is stored as its own file. Those files are named after the document, e.g., the answer for report.pdf is stored as report_result{0}."
|
||||
|
||||
-- Progress
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T439787878"] = "Progress"
|
||||
|
||||
-- File format
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T450269462"] = "File format"
|
||||
|
||||
-- Enter one punctuation or symbol character.
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::ASSISTANTBATCHPROCESSING::T469253621"] = "Enter one punctuation or symbol character."
|
||||
|
||||
@@ -637,15 +649,15 @@ UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGCSVSEPARA
|
||||
-- Custom character
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGCSVSEPARATOREXTENSIONS::T719177757"] = "Custom character"
|
||||
|
||||
-- One file per document
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGOUTPUTMODEEXTENSIONS::T1430232553"] = "One file per document"
|
||||
|
||||
-- One CSV results table, where each answer becomes one row
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGOUTPUTMODEEXTENSIONS::T1515293131"] = "One CSV results table, where each answer becomes one row"
|
||||
|
||||
-- Unknown output mode
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGOUTPUTMODEEXTENSIONS::T2013180377"] = "Unknown output mode"
|
||||
|
||||
-- One Markdown file per document
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGOUTPUTMODEEXTENSIONS::T2420177746"] = "One Markdown file per document"
|
||||
|
||||
-- Use a free prompt
|
||||
UI_TEXT_CONTENT["AISTUDIO::ASSISTANTS::BATCHPROCESSING::BATCHPROCESSINGPROMPTSOURCEEXTENSIONS::T1144335"] = "Use a free prompt"
|
||||
|
||||
@@ -3175,6 +3187,9 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CHATROLEEXTENSIONS::T601166687"] = "AI"
|
||||
-- Edit Message
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Edit Message"
|
||||
|
||||
-- Table {0} ({1})
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1340759627"] = "Table {0} ({1})"
|
||||
|
||||
-- Do you really want to remove this message?
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Do you really want to remove this message?"
|
||||
|
||||
@@ -3199,6 +3214,12 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2093355991"] = "Removes
|
||||
-- Regenerate Message
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2308444540"] = "Regenerate Message"
|
||||
|
||||
-- Failed to export this message, because the file format '{0}' is unknown.
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2544592344"] = "Failed to export this message, because the file format '{0}' is unknown."
|
||||
|
||||
-- Export AI response
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T2822776450"] = "Export AI response"
|
||||
|
||||
-- Number of attachments
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3018847255"] = "Number of attachments"
|
||||
|
||||
@@ -3220,9 +3241,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Remove
|
||||
-- No, keep it
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4188329028"] = "No, keep it"
|
||||
|
||||
-- Export Chat to Microsoft Word
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T861873672"] = "Export Chat to Microsoft Word"
|
||||
|
||||
-- The file '{0}' is currently not available and was not sent.
|
||||
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTTEXT::T1432544573"] = "The file '{0}' is currently not available and was not sent."
|
||||
|
||||
@@ -6862,6 +6880,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T26
|
||||
-- Default column separator
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T2745158463"] = "Default column separator"
|
||||
|
||||
-- Choose the format of new result files. Everything except Markdown is converted by Pandoc.
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T2760965660"] = "Choose the format of new result files. Everything except Markdown is converted by Pandoc."
|
||||
|
||||
-- Preselect batch processing options?
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T2849251744"] = "Preselect batch processing options?"
|
||||
|
||||
@@ -6919,6 +6940,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T39
|
||||
-- Output
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T4000727844"] = "Output"
|
||||
|
||||
-- Default file format
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T4046754119"] = "Default file format"
|
||||
|
||||
-- The configured default policy no longer exists. Select another policy before starting a policy-based batch run.
|
||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::SETTINGS::SETTINGSDIALOGBATCHPROCESSING::T438852523"] = "The configured default policy no longer exists. Select another policy before starting a policy-based batch run."
|
||||
|
||||
@@ -9967,6 +9991,30 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::EXTERNALHTTPCLIENTTIMEOUT::T599774443"] = "The
|
||||
-- policy files
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::EXTERNALHTTPCLIENTTIMEOUT::T632340680"] = "policy files"
|
||||
|
||||
-- OpenDocument Text (.odt), e.g. LibreOffice
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T1612025407"] = "OpenDocument Text (.odt), e.g. LibreOffice"
|
||||
|
||||
-- LaTeX (.tex)
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T2233607007"] = "LaTeX (.tex)"
|
||||
|
||||
-- Markdown (.md)
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T2319970170"] = "Markdown (.md)"
|
||||
|
||||
-- Table (.tsv)
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T293798559"] = "Table (.tsv)"
|
||||
|
||||
-- Microsoft Word (.docx)
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T3054800422"] = "Microsoft Word (.docx)"
|
||||
|
||||
-- Webpage (.html)
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T3651679344"] = "Webpage (.html)"
|
||||
|
||||
-- Table (.csv)
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T530872684"] = "Table (.csv)"
|
||||
|
||||
-- Unknown format
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXPORTFORMATEXTENSIONS::T677355172"] = "Unknown format"
|
||||
|
||||
-- The file type of '{0}' could not be determined, so the file was not sent.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::FILEEXTRACTIONRESULTEXTENSIONS::T1459702734"] = "The file type of '{0}' could not be determined, so the file was not sent."
|
||||
|
||||
@@ -10069,17 +10117,20 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOC::T695293525"] = "AI Studio couldn't fin
|
||||
-- AI Studio couldn't install Pandoc.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOC::T932858631"] = "AI Studio couldn't install Pandoc."
|
||||
|
||||
-- Pandoc is required for Microsoft Word export.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T1473115556"] = "Pandoc is required for Microsoft Word export."
|
||||
-- The export succeeded.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T1713926719"] = "The export succeeded."
|
||||
|
||||
-- Pandoc Installation
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T185447014"] = "Pandoc Installation"
|
||||
-- The export failed.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T1895034475"] = "The export failed."
|
||||
|
||||
-- Error during Microsoft Word export
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T3290596792"] = "Error during Microsoft Word export"
|
||||
-- Only text messages can be exported.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T3576815370"] = "Only text messages can be exported."
|
||||
|
||||
-- Microsoft Word export successful
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PANDOCEXPORT::T4256043333"] = "Microsoft Word export successful"
|
||||
-- The export succeeded.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLAINFILEEXPORT::T1713926719"] = "The export succeeded."
|
||||
|
||||
-- The export failed.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLAINFILEEXPORT::T1895034475"] = "The export failed."
|
||||
|
||||
-- Text
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::PLUGINSYSTEM::ASSISTANTS::DATAMODEL::ASSISTANTCOMPONENTTYPEEXTENSIONS::T1041509726"] = "Text"
|
||||
@@ -10876,8 +10927,8 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::MEDIATRANSCRIPTIONSERVICE::T63285243
|
||||
-- Pandoc Installation
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
||||
|
||||
-- Pandoc may be required for importing files.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T2596465560"] = "Pandoc may be required for importing files."
|
||||
-- AI Studio needs Pandoc for this, but it is not available.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T2610026134"] = "AI Studio needs Pandoc for this, but it is not available."
|
||||
|
||||
-- This plugin archive declares itself as managed by a config server. Only the IT department of your organization might deploy such plugins.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PLUGININSTALLSERVICE::T1138181282"] = "This plugin archive declares itself as managed by a config server. Only the IT department of your organization might deploy such plugins."
|
||||
@@ -11095,9 +11146,6 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::SOURCEEXTENSIONS::T4174900468"] = "Sources pro
|
||||
-- Sources provided by the AI
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SOURCEEXTENSIONS::T4261248356"] = "Sources provided by the AI"
|
||||
|
||||
-- Pandoc Installation
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::USERFILE::T185447014"] = "Pandoc Installation"
|
||||
|
||||
-- The file path is null or empty and the file therefore can not be loaded.
|
||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::USERFILE::T932243993"] = "The file path is null or empty and the file therefore can not be loaded."
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using AIStudio.Chat;
|
||||
using AIStudio.Dialogs;
|
||||
using AIStudio.Dialogs.Settings;
|
||||
using AIStudio.Tools.AssistantSessions;
|
||||
using AIStudio.Tools.Services;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
#if !DEBUG
|
||||
@@ -28,6 +29,9 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
|
||||
[Inject]
|
||||
private IDialogService DialogService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private PandocAvailabilityService PandocAvailability { get; init; } = null!;
|
||||
|
||||
protected override Tools.Components Component => Tools.Components.PROMPT_OPTIMIZER_ASSISTANT;
|
||||
|
||||
protected override string Title => T("Prompt Optimizer");
|
||||
@@ -581,7 +585,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
|
||||
this.isLoadingCustomPromptGuide = true;
|
||||
|
||||
// A failure was already reported by UserFile.LoadFileData, so we only keep the content:
|
||||
var extraction = await UserFile.LoadFileData(fileAttachment.FilePath, this.RustService, this.DialogService);
|
||||
var extraction = await UserFile.LoadFileData(fileAttachment.FilePath, this.RustService, this.PandocAvailability);
|
||||
this.customPromptingGuidelineContent = extraction.HasUsableContent ? extraction.Content : string.Empty;
|
||||
}
|
||||
catch
|
||||
|
||||
Reference in new issue
Block a user