Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/addons/addons/ai-integration/_manifest_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ const manifest = {
{
"id": "GeminiAPIKey",
"name": "Gemini API Key",
"type": "long_string",
"type": "long_password",
"default": "",
},
{
"id": "OpenRouterAPIKey",
"name": "OpenRouter API Key",
"type": "long_string",
"type": "long_password",
"default": "",
}
],
Expand Down
95 changes: 29 additions & 66 deletions src/addons/addons/ai-integration/userscript.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,24 @@ import main from "./main.js";
import { saveSession, deleteSession, loadSessionsForProject, saveMetadata, loadMetadata } from "./helpers/db.js";
const {API_HOST} = require('../../../lib/brand.js');

let authToken = {};
const AI_INTEGRATION = {
AI_currently_blabbering: false,
CodeChunks: [],
AllCodeChunksEverAdded: [],
processedCodeChunks: [],
errorsDetected: [],

sessions: [],
activeSessionId: null,
nextSessionId: 1,
currentProjectId: '0',

popupOpen: false,
canUse: true,
AIModels: [],
};

let authToken = {};
var mainWorkspace;

class ChatSession {
Expand Down Expand Up @@ -43,68 +59,13 @@ window.addEventListener('blockError', (event) => {
document.AI_INTEGRATION.errorsDetected.push(event.detail);
});

document.AI_INTEGRATION = { //probably the dumbest way to possibly do this, it just make debugging alot easier (will do it properly later)
CodeChunks: [],
AllCodeChunksEverAdded: [],
processedCodeChunks: [],
errorsDetected: [],

sessions: [],
activeSessionId: null,
nextSessionId: 1,
currentProjectId: '0',

popupOpen: false,
canUse: true,
AIModels: [],
};

document.AI_INTEGRATION.createNewSession = function() {
const newId = this.nextSessionId++;
const newSession = new ChatSession(newId, this.currentProjectId);
this.sessions.push(newSession);
this.activeSessionId = newId;

saveSession(newSession.toJSON());
saveMetadata(`${this.currentProjectId}_nextSessionId`, this.nextSessionId);
saveMetadata(`${this.currentProjectId}_activeSessionId`, this.activeSessionId);

return newSession;
};

document.AI_INTEGRATION.getActiveSession = function() {
if (!this.activeSessionId) return null;
return this.sessions.find(s => s.id === this.activeSessionId);
};

document.AI_INTEGRATION.closeSession = function(sessionId) {
const sessionIndex = this.sessions.findIndex(s => s.id === sessionId);
if (sessionIndex === -1) return;

this.sessions.splice(sessionIndex, 1);
deleteSession(sessionId);

if (this.activeSessionId === sessionId) {
if (this.sessions.length > 0) {
const newActiveIndex = Math.max(0, sessionIndex - 1);
this.activeSessionId = this.sessions[newActiveIndex].id;
} else {
this.activeSessionId = null;
}
saveMetadata(`${this.currentProjectId}_activeSessionId`, this.activeSessionId);
}
};

document.AI_INTEGRATION.updateAndSaveSession = function(session) {
if (session) {
saveSession(session.toJSON());
}
};

document.AI_INTEGRATION.saveActiveSessionMetadata = function() {
saveMetadata(`${this.currentProjectId}_activeSessionId`, this.activeSessionId);
};
// TODO: possibly push this into the addons api?
document.AI_INTEGRATION = AI_INTEGRATION;

// TODO: dont use global events
window.addEventListener('blockError', (event) => {
AI_INTEGRATION.errorsDetected.push(event.detail);
});

function workspaceOverride() {
if (typeof Blockly !== 'undefined') {
Expand All @@ -119,9 +80,10 @@ function workspaceOverride() {
}
workspaceOverride();

// TODO: this should use a global hook
document.addEventListener("mousemove", (event) => {
document.AI_INTEGRATION.X_COORDINATE = event.clientX;
document.AI_INTEGRATION.Y_COORDINATE = event.clientY;
AI_INTEGRATION.X_COORDINATE = event.clientX;
AI_INTEGRATION.Y_COORDINATE = event.clientY;
});

export default async function ({ addon, console }) {
Expand Down Expand Up @@ -182,7 +144,7 @@ export default async function ({ addon, console }) {
authToken.openrouter = addon.settings.get("OpenRouterAPIKey");

if (authToken.gemini == "" && authToken.openrouter == "") {
document.AI_INTEGRATION.canUse = false;
AI_INTEGRATION.canUse = false;
window.addEventListener('ai-button-clicked', function () {
main.createBasePopup(2, "");
});
Expand All @@ -203,7 +165,7 @@ export default async function ({ addon, console }) {
}
})
.then(data => {
document.AI_INTEGRATION.AIModels = data;
AI_INTEGRATION.AIModels = data;
helpers.updateAIModels(authToken.gemini, authToken.openrouter);
})
.catch(error => {
Expand Down Expand Up @@ -278,6 +240,7 @@ export default async function ({ addon, console }) {
}
});

// TODO: dont use global events
window.addEventListener('ai-button-clicked', function () {
main.startNewSessionWithPrompt(2, "");
});
Expand Down
23 changes: 12 additions & 11 deletions src/addons/settings/settings.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (C) 2021-2023 Thomas Weber
* Copyright (C) 2021-2025 Thomas Weber
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
Expand Down Expand Up @@ -428,23 +428,24 @@ const Setting = ({
/>
</React.Fragment>
)}
{(setting.type === 'string' || setting.type === 'long_string' || setting.type === 'untranslated') && (
{(setting.type === 'string' || setting.type === 'long_string' || setting.type === 'untranslated' ||
setting.type === 'password' || setting.type === 'long_password') && (
<React.Fragment>
{label}
<TextInput
id={uniqueId}
type="text"
type={setting.type === 'password' || setting.type === 'long_password' ? 'password' : 'text'}
value={value}
className={setting.type === 'long_string' ? styles.longStringSetting : ''}
className={setting.type === 'long_string' || setting.type === 'long_password' ? styles.longStringSetting : ''}
onChange={newValue => SettingsStore.setAddonSetting(addonId, settingId, newValue)}
/>
{setting.type !== 'long_string' && (
<ResetButton
addonId={addonId}
settingId={settingId}
forTextInput
/>
)}
{setting.type !== 'long_string' && setting.type !== 'long_password' && (
<ResetButton
addonId={addonId}
settingId={settingId}
forTextInput
/>
)}
</React.Fragment>
)}
{setting.type === 'color' && (
Expand Down