···
console.log("Cleaned response:", cleanResponse);
497
+
// For safety, preprocess JavaScript code in JSON to escape problematic characters
498
+
cleanResponse = cleanResponse.replace(/"code"\s*:\s*(`|")([^`"]*?)(`|")/g, function(match, q1, code, q3) {
499
+
// Replace all literal backslashes with double backslashes in the code string
500
+
const escapedCode = code.replace(/\\/g, "\\\\");
501
+
return `"code":${q1}${escapedCode}${q3}`;
// Check if response contains tool calls
499
-
const toolResponse = JSON.parse(cleanResponse);
506
+
const toolResponse = safeJsonParse(cleanResponse);
toolResponse.tool_calls &&
Array.isArray(toolResponse.tool_calls)
···
followUpContent = followUpContent.trim();
console.log("Follow-up response:", followUpContent);
612
-
if (followUpContent === "COMPLETE") {
620
+
followUpContent === "COMPLETE" ||
621
+
followUpContent === '"COMPLETE"'
statusDiv.textContent = "AI SATISFIED - TASK COMPLETE";
setTimeout(() => (statusDiv.textContent = ""), 3000);
···
/\{[\s\S]*"tool_calls"[\s\S]*\}/,
627
-
const toolResponse = JSON.parse(jsonMatch[0]);
637
+
// Preprocess JavaScript code in JSON to escape problematic characters
638
+
let cleanJson = jsonMatch[0].replace(/"code"\s*:\s*(`|")([^`"]*?)(`|")/g, function(match, q1, code, q3) {
639
+
// Replace all literal backslashes with double backslashes in the code string
640
+
const escapedCode = code.replace(/\\/g, "\\\\");
641
+
return `"code":${q1}${escapedCode}${q3}`;
644
+
const toolResponse = safeJsonParse(cleanJson);
toolResponse.tool_calls &&
Array.isArray(toolResponse.tool_calls)
···
683
+
// Debug helper for JSON parsing issues
684
+
function safeJsonParse(jsonString) {
686
+
return JSON.parse(jsonString);
688
+
console.error("JSON parse error:", error);
689
+
console.error("Problem JSON:", jsonString);
690
+
// Try to escape any unescaped control characters
691
+
const escapedJson = jsonString.replace(/[\u0000-\u001F]/g, match => {
692
+
return '\\u' + ('0000' + match.charCodeAt(0).toString(16)).slice(-4);
695
+
return JSON.parse(escapedJson);
696
+
} catch (secondError) {
697
+
console.error("Second parse attempt failed:", secondError);
698
+
throw error; // Throw the original error
// Handle Ctrl+Enter in textarea
667
-
document.addEventListener("DOMContentLoaded", function () {
669
-
.getElementById("codeEditor")
670
-
.addEventListener("keydown", function (e) {
671
-
if (e.ctrlKey && e.key === "Enter") {
672
-
e.preventDefault();
673
-
generateAndExecute();
704
+
function setupCtrlEnterHandler() {
705
+
const codeEditor = document.getElementById("codeEditor");
707
+
// Remove any previous event listeners first (to avoid duplicates)
708
+
codeEditor.removeEventListener("keydown", ctrlEnterHandler);
709
+
// Add a new event listener
710
+
codeEditor.addEventListener("keydown", ctrlEnterHandler);
712
+
console.error("codeEditor element not found, will retry");
713
+
// Retry after a short delay
714
+
setTimeout(setupCtrlEnterHandler, 100);
718
+
// Define the handler function separately so it can be added/removed consistently
719
+
function ctrlEnterHandler(e) {
720
+
if (e.ctrlKey && e.key === "Enter") {
721
+
e.preventDefault();
722
+
generateAndExecute();
726
+
// Set up the handler immediately
727
+
setupCtrlEnterHandler();
729
+
// Also ensure it's set up when the DOM is fully loaded
730
+
window.addEventListener("DOMContentLoaded", setupCtrlEnterHandler);
731
+
window.addEventListener("load", setupCtrlEnterHandler);
// Update time in status bar