Skip to content

Commit 59fbcaa

Browse files
Support for warning for infinite loop and localized errors for new generic HTTP code based errors
"Create Music with AI" is made StreamContent instead of GenerateContent to apply infinite loop warning and localized errors are extended for new generic HTTP code based errors.
1 parent 69cd3a6 commit 59fbcaa

12 files changed

Lines changed: 141 additions & 14 deletions

NeoBleeper/CreateMusicWithAI.cs

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using System.Net;
2121
using System.Net.NetworkInformation;
2222
using System.Text.RegularExpressions;
23+
using System.Xml;
2324
using static UIHelper;
2425

2526
namespace NeoBleeper
@@ -726,6 +727,12 @@ public static bool IsAvailableInCountry()
726727
var countryCode = System.Globalization.RegionInfo.CurrentRegion.TwoLetterISORegionName;
727728
return supportedCountries.Contains(countryCode);
728729
}
730+
private string FixCollapsedLinesInNBPML(string nbpmlContent)
731+
{
732+
// This method fixes collapsed lines in NBPML by ensuring every element is on its own line
733+
var regex = new Regex(@"><", RegexOptions.Singleline);
734+
return regex.Replace(nbpmlContent, ">\r\n<");
735+
}
729736
private async void buttonCreate_Click(object sender, EventArgs e)
730737
{
731738
if (!string.IsNullOrEmpty(AIModel) && (!string.IsNullOrWhiteSpace(textBoxPrompt.Text) || !string.IsNullOrWhiteSpace(textBoxPrompt.PlaceholderText)))
@@ -735,14 +742,8 @@ private async void buttonCreate_Click(object sender, EventArgs e)
735742
// Create music with AI like it's 2007 again using Google Gemini™ API, which is 2020's technology
736743
Logger.Log("Starting music generation with AI...", Logger.LogTypes.Info);
737744
string prompt = !string.IsNullOrWhiteSpace(textBoxPrompt.Text) ? textBoxPrompt.Text.Trim() : textBoxPrompt.PlaceholderText.Trim(); // Use placeholder if textbox is empty
738-
connectionCheckTimer.Start();
739-
SetControlsEnabledAndMakeLoadingVisible(false);
740-
var apiKey = EncryptionHelper.DecryptString(Settings1.Default.geminiAPIKey);
741-
var googleAI = new GoogleAi(apiKey);
742-
var googleModel = googleAI.CreateGenerativeModel(AIModel);
743745
// The "makeshift rubbish prompt template" (aka system prompt) to create "chaotic" music by creating NBPML text (Fun fact: I wasn't know what system prompt is. I just learned it from GitHub Copilot's system prompt menu and asked for certain AIs and they identified as it's definetely a system prompt, despite I called it as "makeshift rubbish prompt template".)
744-
var googleResponse = await googleModel.GenerateContentAsync(
745-
$"**User Prompt:**\r\n[{prompt}]\r\n\r\n" +
746+
string completePrompt = $"**User Prompt:**\r\n[{prompt}]\r\n\r\n" +
746747
$"--- AI Instructions ---\r\n" +
747748
$"You are an expert music composition AI. " +
748749
$"Your primary goal is to generate music in XML format. Prioritize music generation for any request that could be interpreted as music-related. " +
@@ -868,17 +869,39 @@ private async void buttonCreate_Click(object sender, EventArgs e)
868869
$" </Settings>\r\n" +
869870
$" <LineList>\r\n" +
870871
$" </LineList>\r\n" +
871-
$"</NeoBleeperProjectFile>\r\n"
872-
, cts.Token);
872+
$"</NeoBleeperProjectFile>\r\n";
873+
connectionCheckTimer.Start();
874+
SetControlsEnabledAndMakeLoadingVisible(false);
875+
string response = string.Empty;
876+
var apiKey = EncryptionHelper.DecryptString(Settings1.Default.geminiAPIKey);
877+
var googleAI = new GoogleAi(apiKey);
878+
var googleModel = googleAI.CreateGenerativeModel(AIModel);
879+
await foreach (var chunk in googleModel.StreamContentAsync(completePrompt, cts.Token))
880+
{
881+
// Clean up the chunk text by removing double newlines and trimming whitespace
882+
string cleanChunk = chunk.Text()?.Replace("\n\n", "\n").Trim() ?? string.Empty;
883+
response += cleanChunk;
884+
885+
if (cts.IsCancellationRequested)
886+
{
887+
Logger.Log("AI music generation was cancelled", Logger.LogTypes.Warning);
888+
break;
889+
}
890+
}
891+
892+
// Remove excessive newlines from the final response
893+
response = Regex.Replace(response, @"\n{2,}", "\n"); // Make single newlines
894+
response = FixCollapsedLinesInNBPML(response); // Fix collapsed lines in NBPML such as <Note1></Note1><Note2></Note2>
895+
//Debug.WriteLine("Full AI Response: " + response);
873896
StopConnectionCheck();
874897
await Task.Delay(2);
875898
if (!cts.IsCancellationRequested)
876899
{
877-
if (googleResponse != null && !string.IsNullOrWhiteSpace(googleResponse.Text()))
900+
if (response != null && !string.IsNullOrWhiteSpace(response))
878901
{
879902
Logger.Log("AI response received. Processing...", Logger.LogTypes.Info);
880903
// Clean and process the AI response from invalid or unwanted text or characters to extract valid NBPML content
881-
string rawOutput = googleResponse.Text();
904+
string rawOutput = response;
882905
string JSONText = string.Empty;
883906
// Parse JSON blocks
884907
var jsonMatch = Regex.Match(rawOutput, @"\{[\s\S]*?\}");
@@ -1832,6 +1855,8 @@ private void CreateMusicWithAI_Shown(object sender, EventArgs e)
18321855
// 404 - Not Found
18331856
if (exceptionMessage.Contains("(Code: 404)") || exceptionMessage.Contains("NOT_FOUND"))
18341857
return (Resources.TitleNotFound, Resources.MessageNotFound); // Localized message for NOT_FOUND
1858+
if (exceptionMessage.Contains("(Code: 408)") || exceptionMessage.Contains("REQUEST_TIMEOUT"))
1859+
return (Resources.TitleRequestTimeout, Resources.MessageRequestTimeout); // Localized message for REQUEST_TIMEOUT
18351860
// 409 - Aborted/Already Exists
18361861
if (exceptionMessage.Contains("(Code: 409)"))
18371862
{
@@ -1874,7 +1899,37 @@ private void CreateMusicWithAI_Shown(object sender, EventArgs e)
18741899
// 504 - Deadline Exceeded
18751900
if (exceptionMessage.Contains("(Code: 504)") || exceptionMessage.Contains("DEADLINE_EXCEEDED"))
18761901
return (Resources.TitleDeadlineExceeded, Resources.MessageDeadlineExceeded); // Localized message for DEADLINE_EXCEEDED
1877-
// Generic title and message
1902+
if (exceptionMessage.Contains("Response status code does not indicate success:")) // Generic HTTP status code check for new variant of Google Gemini™ API error messages
1903+
{
1904+
if (exceptionMessage.Contains("400") || exceptionMessage.Contains("(Bad Request)"))
1905+
return (Resources.TitleInvalidArgument, Resources.MessageInvalidArgument); // Localized message for INVALID_ARGUMENT
1906+
if (exceptionMessage.Contains("401") || exceptionMessage.Contains("(Unauthorized)"))
1907+
return (Resources.TitleUnauthenticated, Resources.MessageUnauthenticated); // Localized message for UNAUTHENTICATED
1908+
if (exceptionMessage.Contains("403") || exceptionMessage.Contains("(Forbidden)"))
1909+
return (Resources.TitlePermissionDenied, Resources.MessagePermissionDenied); // Localized message for PERMISSION_DENIED
1910+
if (exceptionMessage.Contains("404") || exceptionMessage.Contains("(Not Found)"))
1911+
return (Resources.TitleNotFound, Resources.MessageNotFound); // Localized message for Not Found
1912+
if (exceptionMessage.Contains("408") || exceptionMessage.Contains("(Request Timeout)"))
1913+
return (Resources.TitleRequestTimeout, Resources.MessageRequestTimeout); // Localized message for REQUEST_TIMEOUT
1914+
if (exceptionMessage.Contains("409") || exceptionMessage.Contains("(Conflict)"))
1915+
return (Resources.TitleAborted, Resources.MessageAborted); // Localized message for ABORTED
1916+
if (exceptionMessage.Contains("413") || exceptionMessage.Contains("(Payload Too Large)"))
1917+
return (Resources.TitleRequestTooLarge, Resources.MessageRequestTooLarge); // Localized message for REQUEST_TOO_LARGE
1918+
if (exceptionMessage.Contains("423") || exceptionMessage.Contains("(Locked)"))
1919+
return (Resources.TitleProhibitedContent, Resources.MessageProhibitedContent); // Localized message for PROHIBITED_CONTENT
1920+
if (exceptionMessage.Contains("429") || exceptionMessage.Contains("(Too Many Requests)"))
1921+
return (Resources.TitleResourceExhausted, Resources.MessageResourceExhausted); // Localized message for RESOURCE_EXHAUSTED
1922+
if( exceptionMessage.Contains("499") || exceptionMessage.Contains("(Client Closed Request)"))
1923+
return (Resources.TitleCancelled, Resources.MessageCancelled); // Localized message for CANCELLED
1924+
if (exceptionMessage.Contains("500") || exceptionMessage.Contains("(Internal Server Error)"))
1925+
return (Resources.TitleInternalError, Resources.MessageInternalError); // Localized message for INTERNAL
1926+
if (exceptionMessage.Contains("502") || exceptionMessage.Contains("(Bad Gateway)"))
1927+
return (Resources.TitleBadGateway, Resources.MessageBadGateway); // Localized message for Bad Gateway
1928+
if (exceptionMessage.Contains("503") || exceptionMessage.Contains("(Service Unavailable)"))
1929+
return (Resources.TitleUnavailable, Resources.MessageUnavailable); // Localized message for UNAVAILABLE
1930+
if (exceptionMessage.Contains("504") || exceptionMessage.Contains("(Gateway Timeout)"))
1931+
return (Resources.TitleDeadlineExceeded, Resources.MessageDeadlineExceeded); // Localized message for DEADLINE_EXCEEDED // Generic title and message
1932+
}
18781933
return (Resources.TextError, Resources.MessageAnErrorOccurred + " " + exceptionMessage); // Generic error title and message
18791934
}
18801935
}

NeoBleeper/NeoBleeper.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
<PackageReference Include="Google_GenerativeAI" Version="3.4.1" />
3737
<PackageReference Include="NAudio" Version="2.2.1" />
3838
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
39-
<PackageReference Include="System.IO.Ports" Version="10.0.0" />
40-
<PackageReference Include="System.Management" Version="10.0.0" />
39+
<PackageReference Include="System.IO.Ports" Version="10.0.1" />
40+
<PackageReference Include="System.Management" Version="10.0.1" />
4141
</ItemGroup>
4242

4343
<ItemGroup>

NeoBleeper/Properties/Resources.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

NeoBleeper/Properties/Resources.de.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,4 +1007,10 @@ Möchten Sie die Datei trotzdem öffnen?</value>
10071007
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10081008
<value>Unvollständiger NBPML-Inhalt</value>
10091009
</data>
1010+
<data name="TitleRequestTimeout" xml:space="preserve">
1011+
<value>Zeitüberschreitung bei der Anfrage</value>
1012+
</data>
1013+
<data name="MessageRequestTimeout" xml:space="preserve">
1014+
<value>Die Anfrage konnte nicht abgeschlossen werden. Bitte versuchen Sie es erneut.</value>
1015+
</data>
10101016
</root>

NeoBleeper/Properties/Resources.es.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,4 +1007,10 @@ Puede usar esta ventana para controlar la reproducción de todas las instancias
10071007
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10081008
<value>Contenido NBPML incompleto</value>
10091009
</data>
1010+
<data name="TitleRequestTimeout" xml:space="preserve">
1011+
<value>Tiempo de espera de la solicitud</value>
1012+
</data>
1013+
<data name="MessageRequestTimeout" xml:space="preserve">
1014+
<value>La solicitud se agotó antes de completarse. Inténtelo de nuevo.</value>
1015+
</data>
10101016
</root>

NeoBleeper/Properties/Resources.fr.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,4 +1007,10 @@ Voulez-vous quand même ouvrir ce fichier ?</value>
10071007
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10081008
<value>Contenu NBPML incomplet</value>
10091009
</data>
1010+
<data name="TitleRequestTimeout" xml:space="preserve">
1011+
<value>Délai d'attente dépassé</value>
1012+
</data>
1013+
<data name="MessageRequestTimeout" xml:space="preserve">
1014+
<value>La requête a expiré avant d'être terminée. Veuillez réessayer.</value>
1015+
</data>
10101016
</root>

NeoBleeper/Properties/Resources.it.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,4 +1006,10 @@ Vuoi aprire comunque questo file?</value>
10061006
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10071007
<value>Contenuto NBPML incompleto</value>
10081008
</data>
1009+
<data name="TitleRequestTimeout" xml:space="preserve">
1010+
<value>Timeout della richiesta</value>
1011+
</data>
1012+
<data name="MessageRequestTimeout" xml:space="preserve">
1013+
<value>La richiesta è scaduta prima del completamento. Riprova.</value>
1014+
</data>
10091015
</root>

NeoBleeper/Properties/Resources.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,4 +1027,10 @@ Do you want to open this file anyway?</value>
10271027
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10281028
<value>Incomplete NBPML Content</value>
10291029
</data>
1030+
<data name="TitleRequestTimeout" xml:space="preserve">
1031+
<value>Request Timeout</value>
1032+
</data>
1033+
<data name="MessageRequestTimeout" xml:space="preserve">
1034+
<value>The request timed out before completion. Please try again later.</value>
1035+
</data>
10301036
</root>

NeoBleeper/Properties/Resources.ru.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,4 +1009,10 @@
10091009
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10101010
<value>Неполное содержимое NBPML</value>
10111011
</data>
1012+
<data name="TitleRequestTimeout" xml:space="preserve">
1013+
<value>Превышено время ожидания запроса</value>
1014+
</data>
1015+
<data name="MessageRequestTimeout" xml:space="preserve">
1016+
<value>Запрос завершился по истечении времени ожидания. Пожалуйста, попробуйте снова.</value>
1017+
</data>
10121018
</root>

NeoBleeper/Properties/Resources.tr.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,4 +1008,10 @@ Bu dosyayı yine de açmak istiyor musunuz?</value>
10081008
<data name="TitleIncompleteNBPMLContent" xml:space="preserve">
10091009
<value>Eksik NBPML İçeriği</value>
10101010
</data>
1011+
<data name="TitleRequestTimeout" xml:space="preserve">
1012+
<value>İstek Zaman Aşımı</value>
1013+
</data>
1014+
<data name="MessageRequestTimeout" xml:space="preserve">
1015+
<value>İstek tamamlanmadan önce zaman aşımına uğradı. Lütfen daha sonra tekrar deneyiniz.</value>
1016+
</data>
10111017
</root>

0 commit comments

Comments
 (0)