Skip to content

Commit

Permalink
dco repo in scratchpad
Browse files Browse the repository at this point in the history
  • Loading branch information
nbonamy committed Nov 3, 2024
1 parent bb597f7 commit 3b5d025
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 190 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "witsy",
"productName": "Witsy",
"version": "1.22.0",
"version": "1.22.1",
"description": "Witsy: desktop AI assistant",
"repository": {
"type": "git",
Expand Down
21 changes: 5 additions & 16 deletions src/screens/PromptAnywhere.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ import MessageItem from '../components/MessageItem.vue'
import MessageItemActionCopy from '../components/MessageItemActionCopy.vue'
import MessageItemActionRead from '../components/MessageItemActionRead.vue'
import ResizableHorizontal from '../components/ResizableHorizontal.vue'
import Attachment from 'models/attachment'
import Generator from '../services/generator'
import Attachment from '../models/attachment'
import Message from '../models/message'
import Chat from '../models/chat'
Expand All @@ -61,6 +62,7 @@ const promptChatTimeout = 1000 * 60 * 1
store.load()
// init stuff
const generator = new Generator(store.config)
const audioPlayer = useAudioPlayer(store.config)
const llmFactory = new LlmFactory(store.config)
Expand All @@ -87,7 +89,6 @@ type LastViewed = {
}
let llm: LlmEngine = null
let stopGeneration = false
let addedToHistory = false
let lastSeenChat: LastViewed = null
let mouseDownToClose = false
Expand Down Expand Up @@ -315,7 +316,7 @@ const onClose = () => {
}
const onStopGeneration = () => {
stopGeneration = true
generator.stop()
}
const onPrompt = async ({ prompt, attachment, docrepo }: { prompt: string, attachment: Attachment, docrepo: string }) => {
Expand Down Expand Up @@ -344,19 +345,7 @@ const onPrompt = async ({ prompt, attachment, docrepo }: { prompt: string, attac
chat.value.addMessage(response.value)
// now generate
stopGeneration = false
const stream = await llm.generate(chat.value.model, chat.value.messages.slice(0, -1))
for await (const msg of stream) {
if (stopGeneration) {
llm.stop(stream)
break
}
if (msg.type === 'tool') {
response.value.setToolCall(msg)
} else if (msg.type === 'content') {
response.value.appendText(msg)
}
}
await generator.generate(llm, chat.value.messages, { model: chat.value.model, attachment, docrepo })
// save?
if (store.config.prompt.autosave) {
Expand Down
52 changes: 14 additions & 38 deletions src/screens/ScratchPad.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<EditableText ref="editor" :placeholder="placeholder"/>
</div>
<ScratchpadActionBar :undoStack="undoStack" :redoStack="redoStack" :copyState="copyState" :audioState="audioState" />
<Prompt :chat="chat" :processing="processing" :enable-doc-repo="false" :enable-commands="false" :conversation-mode="conversationMode" />
<Prompt :chat="chat" :processing="processing" :enable-commands="false" :conversation-mode="conversationMode" />
<audio/>
</div>
</template>
Expand All @@ -25,6 +25,7 @@ import EditableText from '../components/EditableText.vue'
import Prompt from '../components/Prompt.vue'
import useAudioPlayer, { AudioStatus } from '../composables/audio_player'
import Dialog from '../composables/dialog'
import Generator from '../services/generator'
import Attachment from '../models/attachment'
import Message from '../models/message'
import Chat from '../models/chat'
Expand All @@ -36,10 +37,6 @@ const { onEvent, emitEvent } = useEventBus()
// load store
store.load()
// init stuff
let llm: LlmEngine = null
let stopGeneration = false
const placeholder = ref(`Start typing your document or
ask Witsy to write something for you!
Expand Down Expand Up @@ -71,6 +68,10 @@ const conversationMode = ref(null)
// init stuff
store.loadSettings()
const audioPlayer = useAudioPlayer(store.config)
const generator = new Generator(store.config)
// init stuff
let llm: LlmEngine = null
const modifiedCheckDelay = 1000
let modifiedCheckTimeout: NodeJS.Timeout = null
let fileUrl: string = null
Expand Down Expand Up @@ -439,22 +440,9 @@ const onSendPrompt = async ({ prompt, attachment, docrepo }: { prompt: string, a
// now build the prompt
let finalPrompt = prompt
if (subject.length > 0) {
const template = store.config.instructions.scratchpad.prompt
finalPrompt = template.replace('{ask}', prompt).replace('{document}', subject)
} else {
// // rag?
// if (docrepo) {
// sources = await window.api.docrepo.query(docrepo, finalPrompt);
// if (sources.length > 0) {
// const context = sources.map((source) => source.content).join('\n\n');
// finalPrompt = this.config.instructions.docquery.replace('{context}', context).replace('{query}', finalPrompt);
// }
// }
}
// log
Expand All @@ -473,25 +461,13 @@ const onSendPrompt = async ({ prompt, attachment, docrepo }: { prompt: string, a
chat.value.addMessage(response)
// now generate
try {
processing.value = true
stopGeneration = false
const stream = await llm.generate(chat.value.model, chat.value.messages.slice(0, -1))
for await (const msg of stream) {
if (stopGeneration) {
llm.stop(stream)
break
}
if (msg.type === 'tool') {
response.setToolCall(msg)
} else if (msg.type === 'content') {
response.appendText(msg)
}
}
} catch (err) {
console.error(err)
response.setText('An error occurred while generating the response.')
}
processing.value = true
await generator.generate(llm, chat.value.messages, {
model: chat.value.model,
attachment: attachment,
docrepo: chat.value.docrepo,
sources: false,
})
// done
emitEvent('llm-done')
Expand Down Expand Up @@ -530,7 +506,7 @@ const onSendPrompt = async ({ prompt, attachment, docrepo }: { prompt: string, a
}
const onStopPrompting = async () => {
stopGeneration = true
generator.stop()
}
</script>
Expand Down
136 changes: 13 additions & 123 deletions src/services/assistant.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,31 @@

import { LlmEngine, LlmCompletionOpts, LlmChunk } from 'multi-llm-ts'
import { LlmEngine, LlmChunk } from 'multi-llm-ts'
import { Configuration } from 'types/config.d'
import { DocRepoQueryResponseItem } from 'types/rag.d'
import Chat, { defaultTitle } from '../models/chat'
import Attachment from '../models/attachment'
import Message from '../models/message'
import LlmFactory from '../llms/llm'
import { store } from './store'
import { countryCodeToName } from './i18n'
import { availablePlugins } from '../plugins/plugins'
import Generator, { GenerationOpts } from './generator'

export interface AssistantCompletionOpts extends LlmCompletionOpts {
export interface AssistantCompletionOpts extends GenerationOpts {
engine?: string
model?: string
save?: boolean
titling?: boolean
attachment?: Attachment
docrepo?: string
overwriteEngineModel?: boolean
systemInstructions?: string
}

export default class {
export default class extends Generator {

config: Configuration
llmFactory: LlmFactory
engine: string
llm: LlmEngine
chat: Chat
stopGeneration: boolean
stream: AsyncIterable<LlmChunk>

constructor(config: Configuration) {
this.config = config
super(config)
this.engine = null
this.llm = null
this.chat = null
Expand Down Expand Up @@ -83,6 +76,9 @@ export default class {
save: true,
titling: true,
... this.llmFactory.getChatEngineModel(),
attachment: null,
docrepo: null,
sources: true,
overwriteEngineModel: false,
systemInstructions: this.config.instructions.default,
}
Expand Down Expand Up @@ -112,6 +108,7 @@ export default class {
// so engine and model are null so we need to keep opts ones...
opts.engine = this.chat.engine || opts.engine
opts.model = this.chat.model || opts.model
opts.docrepo = this.chat.docrepo || opts.docrepo
}

// we need an llm
Expand All @@ -137,7 +134,10 @@ export default class {
callback?.call(null, null)

// generate text
await this.generateText(opts, callback)
const rc = await this.generate(this.llm, this.chat.messages, opts, callback)
if (!rc) {
opts.titling = false
}

// check if we need to update title
if (opts.titling && this.chat.title === defaultTitle) {
Expand All @@ -151,104 +151,6 @@ export default class {

}

async generateText(opts: AssistantCompletionOpts, callback: (chunk: LlmChunk) => void): Promise<void> {

// we need this to be const during generation
const llm = this.llm
const message: Message = this.chat.lastMessage()

try {

// get messages
const messages = this.getRelevantChatMessages()

// rag?
let sources: DocRepoQueryResponseItem[] = [];
if (this.chat.docrepo) {
const userMessage = messages[messages.length - 1];
sources = await window.api.docrepo.query(this.chat.docrepo, userMessage.content);
//console.log('Sources', JSON.stringify(sources, null, 2));
if (sources.length > 0) {
const context = sources.map((source) => source.content).join('\n\n');
const prompt = this.config.instructions.docquery.replace('{context}', context).replace('{query}', userMessage.content);
messages[messages.length - 1] = new Message('user', prompt);
}
}

// now stream
this.stopGeneration = false
this.stream = await llm.generate(opts.model, messages, opts)
for await (const msg of this.stream) {
if (this.stopGeneration) {
break
}
if (msg.type === 'tool') {
message.setToolCall(msg)
} else if (msg.type === 'content') {
if (msg && sources && sources.length > 0) {
msg.done = false
}
message.appendText(msg)
callback?.call(null, msg)
}
}

// append sources
if (sources && sources.length > 0) {

// reduce to unique sources based on metadata.id
const uniqueSourcesMap = new Map();
sources.forEach(source => {
uniqueSourcesMap.set(source.metadata.uuid, source);
})
sources = Array.from(uniqueSourcesMap.values());

// now add them
let sourcesText = '\n\nSources:\n\n'
sourcesText += sources.map((source) => `- [${source.metadata.title}](${source.metadata.url})`).join('\n')
message.appendText({ type: 'content', text: sourcesText, done: true })
callback?.call(null, { text: sourcesText, done: true })
}

} catch (error) {
console.error('Error while generating text', error)
if (error.name !== 'AbortError') {
if (error.status === 401 || error.message.includes('401') || error.message.toLowerCase().includes('apikey')) {
message.setText('You need to enter your API key in the Models tab of <a href="#settings_models">Settings</a> in order to chat.')
opts.titling = false
this.chat.setEngineModel(null, null)
this.resetLlm()
} else if (error.status === 400 && (error.message.includes('credit') || error.message.includes('balance'))) {
message.setText('Sorry, it seems you have run out of credits. Check the balance of your LLM provider account.')
opts.titling = false
} else if (error.status === 429 && (error.message.includes('resource') || error.message.includes('quota'))) {
message.setText('Sorry, it seems you have reached the rate limit of your LLM provider account. Try again later.')
opts.titling = false
} else if (message.content === '') {
message.setText('Sorry, I could not generate text for that prompt.')
opts.titling = false
} else {
message.appendText({ type: 'content', text: '\n\nSorry, I am not able to continue here.', done: true })
opts.titling = false
}
} else {
callback?.call(null, { text: null, done: true })
}
}

// cleanup
this.stream = null
//callback?.call(null, null)

}

async stop() {
if (this.stream) {
await this.llm?.stop(this.stream)
this.stopGeneration = true
}
}

async attach(file: Attachment) {

// make sure last message is from user else create it
Expand Down Expand Up @@ -299,18 +201,6 @@ export default class {

}

getRelevantChatMessages() {
const conversationLength = this.config.llm.conversationLength
const chatMessages = this.chat.messages.filter((msg) => msg.role !== 'system')
const messages = [this.chat.messages[0], ...chatMessages.slice(-conversationLength*2, -1)]
for (const message of messages) {
if (message.attachment && !message.attachment.contents) {
message.attachment.loadContents()
}
}
return messages
}

getLocalizedInstructions(instructions: string) {
const instr = instructions
if (!this.config.general.language) return instr
Expand Down
Loading

0 comments on commit 3b5d025

Please sign in to comment.