diff --git a/.gitignore b/.gitignore
index fa9a4920..71b9810a 100755
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@
*.iml
/install/
*.class
+.env
+
/gitcypress/node_modules/
diff --git a/package-lock.json b/package-lock.json
index 94c1b9ae..1dab8084 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,6 +5,7 @@
"packages": {
"": {
"dependencies": {
+ "dotenv": "^16.4.7",
"jquery": "^3.7.1",
"jsdom-global": "^3.0.2"
},
@@ -1531,6 +1532,18 @@
"node": ">=0.4.0"
}
},
+ "node_modules/dotenv": {
+ "version": "16.4.7",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+ "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
diff --git a/package.json b/package.json
index f4a808a0..730279a1 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"test": "vitest"
},
"dependencies": {
+ "dotenv": "^16.4.7",
"jquery": "^3.7.1",
"jsdom-global": "^3.0.2"
}
diff --git a/src/main/resources/static/css/main.css b/src/main/resources/static/css/main.css
index e14710d9..a68a08f8 100644
--- a/src/main/resources/static/css/main.css
+++ b/src/main/resources/static/css/main.css
@@ -79,6 +79,7 @@ hr {
height: 180px;
}
+
/* These are for the single examle */
.preview-img {
width: 64px;
@@ -448,6 +449,29 @@ form .progress {
color: white;
}
+.log-section {
+ display: none;
+ /* Hide all tabs by default */
+}
+
+.log-section.active-log {
+ display: block !important;
+ /* Show only the active tab */
+}
+
+.log-tab {
+ cursor: pointer;
+ padding: 8px 15px;
+ font-weight: bold;
+ border: none;
+ background: none;
+}
+
+.log-tab.active {
+ border-bottom: 3px solid #007bff;
+ /* Highlight active tab */
+ color: #007bff;
+}
.side_menu_collapse_btn {
position: absolute;
border: none;
diff --git a/src/main/resources/static/js/gw.process.js b/src/main/resources/static/js/gw.process.js
index 31ff40fb..42eb9f26 100644
--- a/src/main/resources/static/js/gw.process.js
+++ b/src/main/resources/static/js/gw.process.js
@@ -797,6 +797,143 @@ GW.process = {
});
},
+ // Add the AI Summarizer function at the end of GW.process
+ aiSummarize: async function () {
+ let aiButton = document.querySelector("#aiSummarizerButton"); // Select the button
+
+ if (!GW.process.editor) {
+ alert("Editor not found!");
+ return;
+ }
+
+ let code = GW.process.editor.getValue().trim();
+ if (!code) {
+ alert("The code editor is empty!");
+ return;
+ }
+
+ // 🌀 Show loading state
+ aiButton.innerHTML =
+ ' Summarizing...';
+ aiButton.disabled = true;
+
+ const OPENAI_API_KEY = "OPEN_API_KEY";
+ const OPENAI_API_URL = "https://api.openai.com/v1/chat/completions";
+
+ let prompt =
+ `Analyze the following code and provide a detailed summary:\n\n${code}\n\n` +
+ "The summary should include:\n" +
+ "- The purpose of the code and its functionality.\n" +
+ "- Key features, algorithms, or logic used.\n" +
+ "- Any input handling and special cases.\n" +
+ "- Performance considerations or optimizations, if applicable.\n" +
+ "- Any recommendations for improvement or optimization.";
+
+ let requestData = {
+ model: "gpt-3.5-turbo",
+ messages: [
+ {
+ role: "system",
+ content:
+ "You are an AI assistant that analyzes code and provides comprehensive summaries.",
+ },
+ { role: "user", content: prompt },
+ ],
+ max_tokens: 300,
+ };
+
+ try {
+ let response = await fetch(OPENAI_API_URL, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${OPENAI_API_KEY}`,
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(requestData),
+ });
+
+ let jsonResponse = await response.json();
+ console.log("Full API Response:", jsonResponse); // 🔍 Debug: Log full response
+
+ if (!jsonResponse.choices || !jsonResponse.choices.length) {
+ alert("Error: Unexpected response format. Check console logs.");
+ return;
+ }
+
+ let summary = jsonResponse.choices[0].message.content.trim();
+
+ // Log summary in AI Output tab instead of showing a modal
+ GW.process.logAIOutput(summary);
+ } catch (error) {
+ console.error("API Request Failed:", error);
+ alert("Error: " + error.message);
+ } finally {
+ // Restore button state
+ aiButton.innerHTML = "Code Summarizer";
+ aiButton.disabled = false;
+ }
+ },
+
+ // Function to log AI Output inside the AI Output tab (with clearing previous content)
+ logAIOutput: function (summary) {
+ let aiOutputDiv = document.getElementById("ai-output-window");
+
+ if (!aiOutputDiv) {
+ console.error("AI Output log section not found!");
+ return;
+ }
+
+ // Clear previous AI output before adding new summary
+ aiOutputDiv.innerHTML = "";
+
+ // Formatting AI summary output
+ let formattedSummary = summary
+ .replace(/\n\d+\./g, "
•") // Convert numbered points to bullet points
+ .replace(/- /g, "
• ") // Convert dashes to bullet points
+ .replace(
+ /Performance Considerations:/g,
+ "
🔹 Performance Considerations:"
+ )
+ .replace(
+ /Key Features and Algorithms:/g,
+ "
🔹 Key Features and Algorithms:"
+ )
+ .replace(
+ /Recommendations for Improvement:/g,
+ "
🔹 Recommendations for Improvement:"
+ );
+
+ // Append the Code summary to the AI Output tab
+ let logEntry = document.createElement("div");
+ logEntry.classList.add("log-entry");
+ logEntry.innerHTML = `📌 Code Summary:
${formattedSummary}`;
+
+ aiOutputDiv.appendChild(logEntry);
+ aiOutputDiv.scrollTop = aiOutputDiv.scrollHeight; // Auto-scroll to the latest entry
+
+ // Automatically switch to AI Output tab
+ GW.process.switchLogTab("log-content-ai", "log-tab-ai");
+ },
+
+ // Function to switch tabs (Logging / AI Output)
+ switchLogTab: function (contentId, tabId) {
+ // Hide all tab content
+ document.querySelectorAll(".log-section").forEach((el) => {
+ el.classList.remove("active-log");
+ });
+
+ // Remove active class from all tabs
+ document.querySelectorAll(".log-tab").forEach((el) => {
+ el.classList.remove("active");
+ });
+
+ // Show the selected tab content
+ document.getElementById(contentId).classList.add("active-log");
+
+ // Set the clicked tab as active
+ document.getElementById(tabId).classList.add("active");
+ },
+
/**
* This function is called after people click on "Details" in the process history table
* @param {*} history_id
@@ -1306,6 +1443,9 @@ GW.process = {
+