Skip to content

Commit

Permalink
prompt anywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
nbonamy committed May 14, 2024
1 parent 90384de commit 7e9a80a
Show file tree
Hide file tree
Showing 18 changed files with 323 additions and 14 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ To use Internet search you need a [Tavily API key](https://app.tavily.com/home).

## DONE

- [x] Prompt anywhere
- [x] Cancel commands
- [x] GPT-4o support
- [x] Different default engine/model for commands
Expand Down
2 changes: 1 addition & 1 deletion build/build_number.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
178
179
5 changes: 5 additions & 0 deletions defaults/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
"key": "Space",
"alt": true,
"ctrl": true
},
"anywhere": {
"key": "Space",
"shift": true,
"ctrl": true
}
},
"engines": {
Expand Down
24 changes: 22 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"katex": "^0.16.10",
"markdown-it": "^14.1.0",
"markdown-it-mark": "^4.0.0",
"markdown-to-text": "^0.1.1",
"minimatch": "^9.0.4",
"mitt": "^3.0.1",
"officeparser": "^4.1.1",
Expand Down
4 changes: 3 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ref, computed, onMounted } from 'vue'
import Main from './screens/Main.vue'
import Wait from './screens/Wait.vue'
import Commands from './screens/Commands.vue'
import PromptAnywhere from './screens/PromptAnywhere.vue'
// add platform name
onMounted(() => {
Expand All @@ -30,7 +31,8 @@ const routes = {
'/': Main,
'/chat': Main,
'/wait': Wait,
'/command': Commands
'/command': Commands,
'/prompt': PromptAnywhere,
}
const currentPath = ref(window.location.hash)
Expand Down
106 changes: 106 additions & 0 deletions src/automations/anywhere.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

import { Configuration } from '../types/config.d'
import { App } from 'electron'
import { loadSettings } from '../main/config'
import { igniteEngine } from '../services/llm'
import { LlmResponse } from '../types/llm.d'
import removeMarkdown from 'markdown-to-text'
import LlmEngine from '../services/engine'
import Automator from './automator'
import Message from '../models/message'
import * as window from '../main/window'

export default class PromptAnywhere {

private llm: LlmEngine
private cancelled: boolean

constructor(llm?: LlmEngine) {
this.llm = llm
this.cancelled = false
}

cancel = async () => {

// close stuff
await window.closeWaitingPanel();
await window.restoreWindows();
await window.releaseFocus();

// record
this.cancelled = true;

}

execPrompt = async (app: App, prompt: string): Promise<void> => {

try {

// config
const config: Configuration = loadSettings(app);
const engine = config.llm.engine;
const model = config.getActiveModel();

// open waiting panel
window.openWaitingPanel();

// we need an llm
if (!this.llm) {
this.llm = igniteEngine(engine, config);
if (!this.llm) {
throw new Error(`Invalid LLM engine: ${engine}`)
}
}

// now prompt llm
console.debug(`Prompting with ${prompt.slice(0, 50)}…`);
const response = await this.promptLlm(model, prompt);
const result = removeMarkdown(response.content, {
stripListLeaders: false,
listUnicodeChar: ''
});

// if cancelled
if (this.cancelled) {
console.debug('Discarding LLM output as command was cancelled');
return
}

// done
await window.closeWaitingPanel();
await window.restoreWindows();
await window.releaseFocus();

// now paste
console.debug(`Processing LLM output: ${result.slice(0, 50)}…`);

// we need an automator
const automator = new Automator();
await automator.pasteText(result)


} catch (error) {
console.error('Error while testing', error);
}

// done waiting
await window.closeWaitingPanel(true);
await window.restoreWindows();
await window.releaseFocus();

}

private promptLlm = (model: string, prompt: string): Promise<LlmResponse> => {

// build messages
const messages: Message[] = [
new Message('user', prompt)
]

// now get it
return this.llm.complete(messages, { model: model })

}


}
11 changes: 7 additions & 4 deletions src/automations/commander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { RunCommandResponse } from '../types/automation.d'
import { LlmResponse } from '../types/llm.d'
import { App, BrowserWindow, Notification } from 'electron'
import { loadSettings } from '../main/config'
import { igniteEngine } from '../services/llm'
import * as window from '../main/window'

import { igniteEngine } from '../services/llm'
import removeMarkdown from 'markdown-to-text'
import Message from '../models/message'
import Automator from './automator'
import LlmEngine from '../services/engine'
import { v4 as uuidv4 } from 'uuid'
import * as window from '../main/window'

const textCache: strDict = {}

Expand Down Expand Up @@ -144,7 +144,10 @@ export default class Commander {
// now prompt llm
console.debug(`Prompting with ${result.prompt.slice(0, 50)}…`);
const response = await this.promptLlm(model, result.prompt);
result.response = response.content;
result.response = removeMarkdown(response.content, {
stripListLeaders: false,
listUnicodeChar: ''
});

// if cancelled
if (this.cancelled) {
Expand Down
21 changes: 17 additions & 4 deletions src/components/Prompt.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<template>
<div class="prompt">
<BIconFileEarmarkPlus class="icon attach" @click="onAttach"/>
<BIconJournalMedical class="icon prompt" @click="onCustomPrompt"/>
<BIconFileEarmarkPlus class="icon attach" @click="onAttach" v-if="enableAttachments" />
<BIconJournalMedical class="icon prompt" @click="onCustomPrompt" v-if="enableCustomPrompts" />
<div class="input" @paste="onPaste">
<div v-if="store.pendingAttachment" class="attachment" @click="onDetach">
<AttachmentView class="attachment" :attachment="store.pendingAttachment" />
</div>
<div>
<textarea v-model="prompt" @keydown="onKeyDown" @keyup="onKeyUp" ref="input" autofocus="true" />
<BIconMagic class="icon command" @click="onCommands" v-if="prompt" />
<BIconMagic class="icon command" @click="onCommands" v-if="enableCommands && prompt" />
</div>
</div>
<BIconStopCircleFill class="icon stop" @click="onStopAssistant" v-if="working" />
Expand Down Expand Up @@ -36,7 +36,19 @@ import useEventBus from '../composables/useEventBus'
const { onEvent, emitEvent } = useEventBus()
const props = defineProps({
chat: Chat
chat: Chat,
enableAttachments: {
type: Boolean,
default: true
},
enableCustomPrompts: {
type: Boolean,
default: true
},
enableCommands: {
type: Boolean,
default: true
}
})
const prompt = ref('')
Expand Down Expand Up @@ -273,6 +285,7 @@ const autoGrow = (element) => {
// reset before calculating
element.style.height = '0px'
element.style.height = Math.min(150, element.scrollHeight) + 'px'
emitEvent('promptResize', element.style.height)
}
}
Expand Down
37 changes: 36 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { wait } from './main/utils';

import AutoUpdater from './main/autoupdate';
import Commander from './automations/commander';
import PromptAnywhere from './automations/anywhere';
import * as config from './main/config';
import * as history from './main/history';
import * as commands from './main/commands';
Expand All @@ -23,6 +24,7 @@ import * as menu from './main/menu';
import * as text from './main/text';

let commander: Commander = null
let anywhere: PromptAnywhere = null

// first-thing: single instance
// on darwin/mas this is done through Info.plist (LSMultipleInstancesProhibited)
Expand Down Expand Up @@ -57,6 +59,7 @@ const registerShortcuts = () => {
shortcuts.registerShortcuts(app, {
chat: window.openMainWindow,
command: Commander.initCommand,
anywhere: window.openPromptAnywhere,
});
}

Expand All @@ -76,6 +79,7 @@ const buildTrayMenu = () => {

return [
{ label: 'New Chat', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.chat), click: window.openMainWindow },
{ label: 'Prompt Anywhere', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.anywhere), click: window.openPromptAnywhere },
{ label: 'Run AI Command', accelerator: shortcuts.shortcutAccelerator(configShortcuts?.command), click: Commander.initCommand },
{ type: 'separator'},
{ label: 'Settings…', click: window.openSettingsWindow },
Expand Down Expand Up @@ -306,7 +310,7 @@ ipcMain.on('run-command', async (event, payload) => {

// cancel any running command
if (commander !== null) {
commander.cancelCommand();
await commander.cancelCommand();
}

// prepare
Expand Down Expand Up @@ -358,3 +362,34 @@ ipcMain.on('run-python-code', async (event, payload) => {
}
}
})

ipcMain.on('prompt-anywhere', async (event, payload) => {

// cancel previous
if (anywhere != null) {
await anywhere.cancel();
}

// do it
anywhere = new PromptAnywhere();
anywhere.execPrompt(app, JSON.parse(payload));

})

ipcMain.on('resize-anywhere', (event, height) => {
window.resizePromptAnywhere(height);
})

ipcMain.on('cancel-anywhere', async () => {

// if cancel on prompt window
await window.closePromptAnywhere();
await window.releaseFocus();

// if cancel on waiting panel
if (anywhere != null) {
console.log('Cancelling anywhere')
await anywhere.cancel();
anywhere = null;
}
})
1 change: 1 addition & 0 deletions src/main/shortcuts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const registerShortcuts = (app: App, callbacks: ShortcutCallbacks) => {
console.info('Registering shortcuts')
registerShortcut(config.shortcuts.chat, callbacks.chat);
registerShortcut(config.shortcuts.command, callbacks.command);
registerShortcut(config.shortcuts.anywhere, callbacks.anywhere);

}

Expand Down
Loading

0 comments on commit 7e9a80a

Please sign in to comment.