Skip to content

Commit

Permalink
modify all prompts
Browse files Browse the repository at this point in the history
  • Loading branch information
nbonamy committed Dec 23, 2024
1 parent e111b92 commit 492054b
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 31 deletions.
32 changes: 20 additions & 12 deletions src/main/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,25 +71,16 @@ export const loadSettings = (source: App|string): Configuration => {
return buildConfig(defaultSettings, JSON.parse(data))
}

export const saveSettings = (dest: App|string, config: anyDict) => {
export const saveSettings = (dest: App|string, config: Configuration) => {
try {

// nullify defaults
nullifyDefaults(config)

// remove instructions that are the same as the default
const settings = JSON.parse(JSON.stringify(config))
for (const instr in settings.instructions) {
const standard = JSON.stringify(defaultSettings.instructions[instr as keyof typeof defaultSettings.instructions])
const current = JSON.stringify(settings.instructions[instr as keyof typeof settings.instructions])
if (standard === current) {
delete settings.instructions[instr]
}
}
nullifyInstructions(config.instructions, defaultSettings.instructions)

// save
const settingsFile = typeof dest === 'string' ? dest : settingsFilePath(dest)
fs.writeFileSync(settingsFile, JSON.stringify(settings, null, 2))
fs.writeFileSync(settingsFile, JSON.stringify(config, null, 2))

} catch (error) {
console.log('Error saving settings data', error)
Expand All @@ -104,3 +95,20 @@ const nullifyDefaults = (settings: anyDict) => {
delete settings.engines.ollama.baseURL
}
}

export const nullifyInstructions = (settings: anyDict, defaults: anyDict) => {
for (const instr in settings) {
if (typeof settings[instr] === 'object') {
nullifyInstructions(settings[instr], defaults[instr])
if (Object.keys(settings[instr]).length === 0) {
delete settings[instr]
}
} else {
const standard = JSON.stringify(defaults[instr as keyof typeof defaults])
const current = JSON.stringify(settings[instr as keyof typeof settings])
if (standard === current) {
delete settings[instr]
}
}
}
}
64 changes: 57 additions & 7 deletions src/settings/SettingsAdvanced.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<input type="number" min="1" v-model="conversationLength" @change="save">
</div>
<div class="group size">
<label>Image Resize</label>
<label>Image resize</label>
<select v-model="imageResize" @change="save">
<option value="0">No resize</option>
<option value="512">Resize largest dimension to 512 pixels</option>
Expand All @@ -25,9 +25,24 @@
</select>
</div>
<div class="group instruction">
<label>Default instructions</label>
<label>System instructions</label>
<div class="subgroup">
<textarea v-model="defaultInstructions" @change="save" />
<select v-model="instructions" @change="onChangeInstructions">
<option value="default">Chat - Instructions</option>
<option value="docquery">Document query - Instructions</option>
<option value="titling">Chat title - Instructions</option>
<option value="titling_user">Chat title - Prompt</option>
<option value="scratchpad.system">Scratchpad - Instructions</option>
<option value="scratchpad.prompt">Scratchpad - Prompt</option>
<option value="scratchpad.spellcheck">Scratchpad - Spellcheck</option>
<option value="scratchpad.improve">Scratchpad - Improve</option>
<option value="scratchpad.takeaways">Scratchpad - Takeaways</option>
<option value="scratchpad.title">Scratchpad - Title</option>
<option value="scratchpad.simplify">Scratchpad - Simplify</option>
<option value="scratchpad.expand">Scratchpad - Expand</option>
<option value="scratchpad.complete">Scratchpad - Complete</option>
</select>
<textarea v-model="prompt" @change="save" />
<a href="#" @click="onResetDefaultInstructions">Reset to default value</a>
</div>
</div>
Expand All @@ -40,7 +55,8 @@ import { ref, } from 'vue'
import { store } from '../services/store'
import defaults from '../../defaults/settings.json'
const defaultInstructions = ref(null)
const prompt = ref(null)
const instructions = ref('default')
const autoVisionSwitch = ref(null)
const autoSavePrompt = ref(null)
const conversationLength = ref(null)
Expand All @@ -49,22 +65,47 @@ const imageResize = ref(null)
const load = () => {
autoVisionSwitch.value = store.config.llm.autoVisionSwitch
autoSavePrompt.value = store.config.prompt.autosave
defaultInstructions.value = store.config.instructions.default || ''
conversationLength.value = store.config.llm.conversationLength || 5
imageResize.value = store.config.llm.imageResize || 768
onChangeInstructions()
}
const onChangeInstructions = () => {
const tokens = instructions.value.split('.')
let promptValue = store.config.instructions
for (const token of tokens) {
promptValue = promptValue[token]
}
prompt.value = promptValue
}
const onResetDefaultInstructions = () => {
defaultInstructions.value = defaults.instructions.default
const tokens = instructions.value.split('.')
let defaultValue = defaults.instructions
for (const token of tokens) {
defaultValue = defaultValue[token]
}
prompt.value = defaultValue
save()
}
const save = () => {
// basic stuff
store.config.llm.autoVisionSwitch = autoVisionSwitch.value
store.config.prompt.autosave = autoSavePrompt.value
store.config.instructions.default = defaultInstructions.value
store.config.llm.conversationLength = conversationLength.value
store.config.llm.imageResize = parseInt(imageResize.value)
// update prompt
const tokens = instructions.value.split('.')
let config = store.config.instructions
for (let i = 0; i < tokens.length - 1; i++) {
config = config[tokens[i]]
}
config[tokens[tokens.length - 1]] = prompt.value
// save
store.saveSettings()
}
Expand Down Expand Up @@ -100,4 +141,13 @@ input::-webkit-inner-spin-button {
margin: 0;
}
.subgroup select {
margin-bottom: 0.5rem;
}
.subgroup textarea {
width: 100%;
height: 100px;
}
</style>
4 changes: 2 additions & 2 deletions src/types/config.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import { EngineCreateOpts, Model } from 'multi-llm-ts'
import { Shortcut, anyDict } from './index.d'
import { Shortcut, strDict } from './index.d'

export type Configuration = {
general: GeneralConfig
Expand Down Expand Up @@ -45,7 +45,7 @@ export interface InstructionsConfig {
titling: string
titling_user: string
docquery: string
scratchpad: { [key: string]: string }
scratchpad: strDict
}

export type AppearanceConfig = {
Expand Down
42 changes: 33 additions & 9 deletions tests/screens/settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,39 @@ test('Settings Advanced', async () => {
expect(store.saveSettings).toHaveBeenCalledOnce()
vi.clearAllMocks()

expect(store.config.instructions.default).not.toBe('bot')
tab.find('.group.instruction textarea').setValue('bot')
expect(store.config.instructions.default).toBe('bot')
expect(store.saveSettings).toHaveBeenCalledOnce()
vi.clearAllMocks()
// helper to get instructions at any level
store.config.instructions.get = (key: string): string => {
const tokens = key.split('.')
let value = store.config.instructions
for (const token of tokens) {
value = value[token]
}
return value
}

const instructions = [
'default', 'titling', 'titling_user', 'docquery', 'scratchpad.system', 'scratchpad.prompt', 'scratchpad.spellcheck',
'scratchpad.improve', 'scratchpad.takeaways', 'scratchpad.title', 'scratchpad.simplify', 'scratchpad.expand', 'scratchpad.complete'
]

for (const instr in instructions) {

// check it is not bot
expect(store.config.instructions.get(instructions[instr])).not.toBe('bot')

// select and set value
await tab.find('.group.instruction select').setValue(instructions[instr])
await tab.find('.group.instruction textarea').setValue('bot')
expect(store.config.instructions.get(instructions[instr])).toBe('bot')
expect(store.saveSettings).toHaveBeenCalledOnce()
vi.clearAllMocks()

// await tab.find('.group.instruction a').trigger('click')
// expect(store.config.instructions.default).not.toBe('bot')
// expect(store.saveSettings).toHaveBeenCalledOnce()
// vi.clearAllMocks()
// reset default
await tab.find('.group.instruction a').trigger('click')
expect(store.config.instructions.get(instructions[instr])).not.toBe('bot')
expect(store.saveSettings).toHaveBeenCalledOnce()
vi.clearAllMocks()

}

})
39 changes: 38 additions & 1 deletion tests/unit/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,41 @@ test('Save settings', () => {
const saved = JSON.parse(JSON.stringify(loaded))
saved.instructions = {}
expect(fs.writeFileSync).toHaveBeenCalledWith('settings.json', JSON.stringify(saved, null, 2))
})
})

test('Nullify instructions', () => {

const defaults = {
key1: 'value1',
key2: 'value2',
dict1: {
key1: 'value1',
key2: 'value2',
}
}

let input = JSON.parse(JSON.stringify(defaults))
let reference = JSON.parse(JSON.stringify(defaults))
config.nullifyInstructions(input, reference)
expect(input).toStrictEqual({})

input = JSON.parse(JSON.stringify(defaults))
reference = JSON.parse(JSON.stringify(defaults))
input.key1 = 'value3'
config.nullifyInstructions(input, reference)
expect(input).toStrictEqual({key1: 'value3'})

input = JSON.parse(JSON.stringify(defaults))
reference = JSON.parse(JSON.stringify(defaults))
input.dict1.key1 = 'value3'
config.nullifyInstructions(input, reference)
expect(input).toStrictEqual({dict1: {key1: 'value3'}})

input = JSON.parse(JSON.stringify(defaults))
reference = JSON.parse(JSON.stringify(defaults))
input.key2 = 'value3'
input.dict1.key2 = 'value4'
config.nullifyInstructions(input, reference)
expect(input).toStrictEqual({key2: 'value3', dict1: {key2: 'value4'}})

})

0 comments on commit 492054b

Please sign in to comment.