diff --git a/.config/ags/modules/sideleft/apis/ai_chatmessage.js b/.config/ags/modules/sideleft/apis/ai_chatmessage.js index cf2498ac8..1c79b3a1c 100644 --- a/.config/ags/modules/sideleft/apis/ai_chatmessage.js +++ b/.config/ags/modules/sideleft/apis/ai_chatmessage.js @@ -12,7 +12,7 @@ const LATEX_DIR = `${GLib.get_user_cache_dir()}/ags/media/latex`; const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/assets/themes/sourceviewtheme.xml`; const CUSTOM_SCHEME_ID = 'custom'; const USERNAME = GLib.get_user_name(); -const CHATGPT_CURSOR = ' ...'; +const AI_MESSAGE_CURSOR = ' ...'; /////////////////////// Custom source view colorscheme ///////////////////////// @@ -34,13 +34,6 @@ loadCustomColorScheme(CUSTOM_SOURCEVIEW_SCHEME_PATH); ////////////////////////////////////////////////////////////////////////////// -function copyToClipboard(text) { - const clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD); - const textVariant = new GLib.Variant('s', text); - clipboard.set_text(textVariant, -1); - clipboard.store(); -} - function substituteLang(str) { const subs = [ { from: 'javascript', to: 'js' }, @@ -265,7 +258,7 @@ const MessageContent = (content) => { const lastLabel = kids[kids.length - 1]; let blockContent = lines.slice(lastProcessed, lines.length).join('\n'); if (!inCode) - lastLabel.label = `${md2pango(blockContent)}${useCursor ? CHATGPT_CURSOR : ''}`; + lastLabel.label = `${md2pango(blockContent)}${useCursor ? AI_MESSAGE_CURSOR : ''}`; else lastLabel.attribute.updateText(blockContent); } diff --git a/.config/ags/modules/sideleft/apis/chatgpt.js b/.config/ags/modules/sideleft/apis/chatgpt.js index 6ea650ad4..c3e657aab 100644 --- a/.config/ags/modules/sideleft/apis/chatgpt.js +++ b/.config/ags/modules/sideleft/apis/chatgpt.js @@ -4,7 +4,7 @@ import Widget from 'resource:///com/github/Aylur/ags/widget.js'; import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; const { Box, Button, Icon, Label, Revealer, Scrollable } = Widget; -import ChatGPT from '../../../services/gpt.js'; +import GPTService from '../../../services/gpt.js'; import { setupCursorHover, setupCursorHoverInfo } from '../../.widgetutils/cursorhover.js'; import { SystemMessage, ChatMessage } from "./ai_chatmessage.js"; import { ConfigToggle, ConfigSegmentedSelection, ConfigGap } from '../../.commonwidgets/configwidgets.js'; @@ -23,14 +23,14 @@ export const chatGPTTabIcon = Icon({ const ProviderSwitcher = () => { const ProviderChoice = (id, provider) => { const providerSelected = MaterialIcon('check', 'norm', { - setup: (self) => self.hook(ChatGPT, (self) => { - self.toggleClassName('invisible', ChatGPT.providerID !== id); + setup: (self) => self.hook(GPTService, (self) => { + self.toggleClassName('invisible', GPTService.providerID !== id); }, 'providerChanged') }); return Button({ tooltipText: provider.description, onClicked: () => { - ChatGPT.providerID = id; + GPTService.providerID = id; providerList.revealChild = false; indicatorChevron.label = 'expand_more'; }, @@ -64,9 +64,9 @@ const ProviderSwitcher = () => { hexpand: true, xalign: 0, className: 'txt-small', - label: ChatGPT.providerID, - setup: (self) => self.hook(ChatGPT, (self) => { - self.label = `${ChatGPT.providers[ChatGPT.providerID]['name']}`; + label: GPTService.providerID, + setup: (self) => self.hook(GPTService, (self) => { + self.label = `${GPTService.providers[GPTService.providerID]['name']}`; }, 'providerChanged') }), indicatorChevron, @@ -89,8 +89,8 @@ const ProviderSwitcher = () => { Box({ className: 'spacing-v-5', vertical: true, - setup: (self) => self.hook(ChatGPT, (self) => { - self.children = Object.entries(ChatGPT.providers) + setup: (self) => self.hook(GPTService, (self) => { + self.children = Object.entries(GPTService.providers) .map(([id, provider]) => ProviderChoice(id, provider)); }, 'initialized'), }) @@ -108,7 +108,7 @@ const ProviderSwitcher = () => { }) } -const ChatGPTInfo = () => { +const GPTInfo = () => { const openAiLogo = Icon({ hpack: 'center', className: 'sidebar-chat-welcome-logo', @@ -147,14 +147,14 @@ const ChatGPTInfo = () => { }); } -export const ChatGPTSettings = () => MarginRevealer({ +const GPTSettings = () => MarginRevealer({ transition: 'slide_down', revealChild: true, extraSetup: (self) => self - .hook(ChatGPT, (self) => Utils.timeout(200, () => { + .hook(GPTService, (self) => Utils.timeout(200, () => { self.attribute.hide(); }), 'newMsg') - .hook(ChatGPT, (self) => Utils.timeout(200, () => { + .hook(GPTService, (self) => Utils.timeout(200, () => { self.attribute.show(); }), 'clear') , @@ -166,7 +166,7 @@ export const ChatGPTSettings = () => MarginRevealer({ hpack: 'center', icon: 'casino', name: 'Randomness', - desc: 'ChatGPT\'s temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1', + desc: 'The model\'s temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1', options: [ { value: 0.00, name: 'Precise', }, { value: 0.50, name: 'Balanced', }, @@ -174,7 +174,7 @@ export const ChatGPTSettings = () => MarginRevealer({ ], initIndex: 2, onChange: (value, name) => { - ChatGPT.temperature = value; + GPTService.temperature = value; }, }), ConfigGap({ vertical: true, size: 10 }), // Note: size can only be 5, 10, or 15 @@ -187,18 +187,18 @@ export const ChatGPTSettings = () => MarginRevealer({ icon: 'cycle', name: 'Cycle models', desc: 'Helps avoid exceeding the API rate of 3 messages per minute.\nTurn this on if you message rapidly.', - initValue: ChatGPT.cycleModels, + initValue: GPTService.cycleModels, onChange: (self, newValue) => { - ChatGPT.cycleModels = newValue; + GPTService.cycleModels = newValue; }, }), ConfigToggle({ icon: 'model_training', name: 'Enhancements', - desc: 'Tells ChatGPT:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points', - initValue: ChatGPT.assistantPrompt, + desc: 'Tells the model:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points', + initValue: GPTService.assistantPrompt, onChange: (self, newValue) => { - ChatGPT.assistantPrompt = newValue; + GPTService.assistantPrompt = newValue; }, }), ] @@ -213,8 +213,8 @@ export const OpenaiApiKeyInstructions = () => Box({ transition: 'slide_down', transitionDuration: 150, setup: (self) => self - .hook(ChatGPT, (self, hasKey) => { - self.revealChild = (ChatGPT.key.length == 0); + .hook(GPTService, (self, hasKey) => { + self.revealChild = (GPTService.key.length == 0); }, 'hasKey') , child: Button({ @@ -227,13 +227,13 @@ export const OpenaiApiKeyInstructions = () => Box({ }), setup: setupCursorHover, onClicked: () => { - Utils.execAsync(['bash', '-c', `xdg-open ${ChatGPT.getKeyUrl}`]); + Utils.execAsync(['bash', '-c', `xdg-open ${GPTService.getKeyUrl}`]); } }) })] }); -const chatGPTWelcome = Box({ +const GPTWelcome = () => Box({ vexpand: true, homogeneous: true, child: Box({ @@ -241,9 +241,9 @@ const chatGPTWelcome = Box({ vpack: 'center', vertical: true, children: [ - ChatGPTInfo(), + GPTInfo(), OpenaiApiKeyInstructions(), - ChatGPTSettings(), + GPTSettings(), ] }) }); @@ -252,16 +252,16 @@ export const chatContent = Box({ className: 'spacing-v-15', vertical: true, setup: (self) => self - .hook(ChatGPT, (box, id) => { - const message = ChatGPT.messages[id]; + .hook(GPTService, (box, id) => { + const message = GPTService.messages[id]; if (!message) return; - box.add(ChatMessage(message, 'ChatGPT')) + box.add(ChatMessage(message, `Model (${GPTService.providers[GPTService.providerID]['name']})`)) }, 'newMsg') , }); const clearChat = () => { - ChatGPT.clear(); + GPTService.clear(); const children = chatContent.get_children(); for (let i = 0; i < children.length; i++) { const child = children[i]; @@ -289,16 +289,16 @@ export const chatGPTCommands = Box({ export const sendMessage = (text) => { // Check if text or API key is empty if (text.length == 0) return; - if (ChatGPT.key.length == 0) { - ChatGPT.key = text; - chatContent.add(SystemMessage(`Key saved to\n\`${ChatGPT.keyPath}\``, 'API Key', chatGPTView)); + if (GPTService.key.length == 0) { + GPTService.key = text; + chatContent.add(SystemMessage(`Key saved to\n\`${GPTService.keyPath}\``, 'API Key', chatGPTView)); text = ''; return; } // Commands if (text.startsWith('/')) { if (text.startsWith('/clear')) clearChat(); - else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${ChatGPT.modelName}\``, '/model', chatGPTView)) + else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${GPTService.modelName}\``, '/model', chatGPTView)) else if (text.startsWith('/prompt')) { const firstSpaceIndex = text.indexOf(' '); const prompt = text.slice(firstSpaceIndex + 1); @@ -306,18 +306,18 @@ export const sendMessage = (text) => { chatContent.add(SystemMessage(`Usage: \`/prompt MESSAGE\``, '/prompt', chatGPTView)) } else { - ChatGPT.addMessage('user', prompt) + GPTService.addMessage('user', prompt) } } else if (text.startsWith('/key')) { const parts = text.split(' '); if (parts.length == 1) chatContent.add(SystemMessage( - `Key stored in:\n\`${ChatGPT.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``, + `Key stored in:\n\`${GPTService.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``, '/key', chatGPTView)); else { - ChatGPT.key = parts[1]; - chatContent.add(SystemMessage(`Updated API Key at\n\`${ChatGPT.keyPath}\``, '/key', chatGPTView)); + GPTService.key = parts[1]; + chatContent.add(SystemMessage(`Updated API Key at\n\`${GPTService.keyPath}\``, '/key', chatGPTView)); } } else if (text.startsWith('/test')) @@ -326,7 +326,7 @@ export const sendMessage = (text) => { chatContent.add(SystemMessage(`Invalid command.`, 'Error', chatGPTView)) } else { - ChatGPT.send(text); + GPTService.send(text); } } @@ -340,7 +340,7 @@ export const chatGPTView = Box({ child: Box({ vertical: true, children: [ - chatGPTWelcome, + GPTWelcome(), chatContent, ] }), diff --git a/.config/ags/modules/sideleft/apis/gemini.js b/.config/ags/modules/sideleft/apis/gemini.js index 5d323ef15..7da16e435 100644 --- a/.config/ags/modules/sideleft/apis/gemini.js +++ b/.config/ags/modules/sideleft/apis/gemini.js @@ -4,7 +4,7 @@ import Widget from 'resource:///com/github/Aylur/ags/widget.js'; import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; const { Box, Button, Icon, Label, Revealer, Scrollable } = Widget; -import Gemini from '../../../services/gemini.js'; +import GeminiService from '../../../services/gemini.js'; import { setupCursorHover, setupCursorHoverInfo } from '../../.widgetutils/cursorhover.js'; import { SystemMessage, ChatMessage } from "./ai_chatmessage.js"; import { ConfigToggle, ConfigSegmentedSelection, ConfigGap } from '../../.commonwidgets/configwidgets.js'; @@ -63,10 +63,10 @@ export const GeminiSettings = () => MarginRevealer({ transition: 'slide_down', revealChild: true, extraSetup: (self) => self - .hook(Gemini, (self) => Utils.timeout(200, () => { + .hook(GeminiService, (self) => Utils.timeout(200, () => { self.attribute.hide(); }), 'newMsg') - .hook(Gemini, (self) => Utils.timeout(200, () => { + .hook(GeminiService, (self) => Utils.timeout(200, () => { self.attribute.show(); }), 'clear') , @@ -86,7 +86,7 @@ export const GeminiSettings = () => MarginRevealer({ ], initIndex: 2, onChange: (value, name) => { - Gemini.temperature = value; + GeminiService.temperature = value; }, }), ConfigGap({ vertical: true, size: 10 }), // Note: size can only be 5, 10, or 15 @@ -99,9 +99,9 @@ export const GeminiSettings = () => MarginRevealer({ icon: 'model_training', name: 'Enhancements', desc: 'Tells Gemini:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points', - initValue: Gemini.assistantPrompt, + initValue: GeminiService.assistantPrompt, onChange: (self, newValue) => { - Gemini.assistantPrompt = newValue; + GeminiService.assistantPrompt = newValue; }, }), ] @@ -116,8 +116,8 @@ export const GoogleAiInstructions = () => Box({ transition: 'slide_down', transitionDuration: 150, setup: (self) => self - .hook(Gemini, (self, hasKey) => { - self.revealChild = (Gemini.key.length == 0); + .hook(GeminiService, (self, hasKey) => { + self.revealChild = (GeminiService.key.length == 0); }, 'hasKey') , child: Button({ @@ -155,8 +155,8 @@ export const chatContent = Box({ className: 'spacing-v-15', vertical: true, setup: (self) => self - .hook(Gemini, (box, id) => { - const message = Gemini.messages[id]; + .hook(GeminiService, (box, id) => { + const message = GeminiService.messages[id]; if (!message) return; box.add(ChatMessage(message, MODEL_NAME)) }, 'newMsg') @@ -164,7 +164,7 @@ export const chatContent = Box({ }); const clearChat = () => { - Gemini.clear(); + GeminiService.clear(); const children = chatContent.get_children(); for (let i = 0; i < children.length; i++) { const child = children[i]; @@ -192,16 +192,16 @@ export const geminiCommands = Box({ export const sendMessage = (text) => { // Check if text or API key is empty if (text.length == 0) return; - if (Gemini.key.length == 0) { - Gemini.key = text; - chatContent.add(SystemMessage(`Key saved to\n\`${Gemini.keyPath}\``, 'API Key', geminiView)); + if (GeminiService.key.length == 0) { + GeminiService.key = text; + chatContent.add(SystemMessage(`Key saved to\n\`${GeminiService.keyPath}\``, 'API Key', geminiView)); text = ''; return; } // Commands if (text.startsWith('/')) { if (text.startsWith('/clear')) clearChat(); - else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${Gemini.modelName}\``, '/model', geminiView)) + else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${GeminiService.modelName}\``, '/model', geminiView)) else if (text.startsWith('/prompt')) { const firstSpaceIndex = text.indexOf(' '); const prompt = text.slice(firstSpaceIndex + 1); @@ -209,18 +209,18 @@ export const sendMessage = (text) => { chatContent.add(SystemMessage(`Usage: \`/prompt MESSAGE\``, '/prompt', geminiView)) } else { - Gemini.addMessage('user', prompt) + GeminiService.addMessage('user', prompt) } } else if (text.startsWith('/key')) { const parts = text.split(' '); if (parts.length == 1) chatContent.add(SystemMessage( - `Key stored in:\n\`${Gemini.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``, + `Key stored in:\n\`${GeminiService.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``, '/key', geminiView)); else { - Gemini.key = parts[1]; - chatContent.add(SystemMessage(`Updated API Key at\n\`${Gemini.keyPath}\``, '/key', geminiView)); + GeminiService.key = parts[1]; + chatContent.add(SystemMessage(`Updated API Key at\n\`${GeminiService.keyPath}\``, '/key', geminiView)); } } else if (text.startsWith('/test')) @@ -229,7 +229,7 @@ export const sendMessage = (text) => { chatContent.add(SystemMessage(`Invalid command.`, 'Error', geminiView)) } else { - Gemini.send(text); + GeminiService.send(text); } } diff --git a/.config/ags/modules/sideleft/apiwidgets.js b/.config/ags/modules/sideleft/apiwidgets.js index 9ae344a1c..ac89b6a66 100644 --- a/.config/ags/modules/sideleft/apiwidgets.js +++ b/.config/ags/modules/sideleft/apiwidgets.js @@ -6,7 +6,7 @@ const { execAsync, exec } = Utils; import { setupCursorHover, setupCursorHoverInfo } from '../.widgetutils/cursorhover.js'; import { contentStack } from './sideleft.js'; // APIs -import ChatGPT from '../../services/gpt.js'; +import GPTService from '../../services/gpt.js'; import Gemini from '../../services/gemini.js'; import { geminiView, geminiCommands, sendMessage as geminiSendMessage, geminiTabIcon } from './apis/gemini.js'; import { chatGPTView, chatGPTCommands, sendMessage as chatGPTSendMessage, chatGPTTabIcon } from './apis/chatgpt.js'; @@ -65,9 +65,9 @@ export const chatEntry = TextView({ acceptsTab: false, className: 'sidebar-chat-entry txt txt-smallie', setup: (self) => self - .hook(ChatGPT, (self) => { - if (APIS[currentApiId].name != 'Assistant (ChatGPT 3.5)') return; - self.placeholderText = (ChatGPT.key.length > 0 ? 'Message ChatGPT...' : 'Enter OpenAI API Key...'); + .hook(GPTService, (self) => { + if (APIS[currentApiId].name != 'Assistant (GPTs)') return; + self.placeholderText = (GPTService.key.length > 0 ? 'Message the model...' : 'Enter API Key...'); }, 'hasKey') .hook(Gemini, (self) => { if (APIS[currentApiId].name != 'Assistant (Gemini Pro)') return;