Skip to content

Commit

Permalink
Fix preset setting bugs (#1038)
Browse files Browse the repository at this point in the history
* add nai min_p
- fix model format change
- move min p to general
- fix missing third party settings
- hide advanced prompt correctly in simple mode
* fix menu always opening in chat
  • Loading branch information
sceuick authored Oct 2, 2024
1 parent 88186e8 commit a596202
Show file tree
Hide file tree
Showing 12 changed files with 142 additions and 28 deletions.
97 changes: 90 additions & 7 deletions common/template-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import peggy from 'peggy'
import { elapsedSince } from './util'
import { v4 } from 'uuid'

type Section = 'system' | 'def' | 'history' | 'post'

export type TemplateOpts = {
continue?: boolean
parts?: Partial<PromptParts>
Expand Down Expand Up @@ -33,6 +35,11 @@ export type TemplateOpts = {
output?: Record<string, { src: string; lines: string[] }>
}

sections?: {
flags: { [key in Section]?: boolean }
sections: { [key in Section]: string[] }
}

/**
* Only allow repeatable placeholders. Excludes iterators, conditions, and prompt parts.
*/
Expand Down Expand Up @@ -168,11 +175,19 @@ export async function parseTemplate(
length?: number
linesAddedCount: number
history?: string[]
sections: NonNullable<TemplateOpts['sections']>
}> {
if (opts.limit) {
opts.limit.output = {}
}

const sections: TemplateOpts['sections'] = {
flags: {},
sections: { system: [], def: [], history: [], post: [] },
}

opts.sections = sections

const parts = opts.parts || {}

if (parts.systemPrompt) {
Expand Down Expand Up @@ -200,6 +215,7 @@ export async function parseTemplate(
// }

/** Replace iterators */
let history: string[] = []
if (opts.limit && opts.limit.output) {
for (const [id, { lines, src }] of Object.entries(opts.limit.output)) {
src
Expand All @@ -215,6 +231,7 @@ export async function parseTemplate(
const trimmed = filled.adding.slice().reverse()
output = output.replace(id, trimmed.join('\n'))
linesAddedCount += filled.linesAddedCount
history = trimmed
}

// Adding the low priority blocks if we still have the budget for them,
Expand All @@ -236,11 +253,15 @@ export async function parseTemplate(
.replace(/\r\n/g, '\n')
.replace(/\n\n+/g, '\n\n')
.trim()

sections.sections.history = history

return {
parsed: result,
inserts: opts.inserts ?? new Map(),
length: await opts.limit?.encoder?.(result),
linesAddedCount,
sections,
}
}

Expand Down Expand Up @@ -324,22 +345,57 @@ function renderNodes(nodes: PNode[], opts: TemplateOpts) {

function renderNode(node: PNode, opts: TemplateOpts, conditionText?: string) {
if (typeof node === 'string') {
fillSection(opts.sections, node)
return node
}

switch (node.kind) {
case 'placeholder': {
return getPlaceholder(node, opts, conditionText)
const result = getPlaceholder(node, opts, conditionText)
// We need to end the definition section prior to filling the history section
// History is the only deterministic marker for the end of the definitions
if (node.value === 'history') {
flagSection(opts.sections, 'def')
}
fillSection(opts.sections, result)
if (node.value === 'history') {
flagSection(opts.sections, 'history')
}
if (node.value === 'system_prompt') {
flagSection(opts.sections, 'system')
}
return result
}

case 'each': {
const result = renderIterator(node.value, node.children, opts)
// See 'placeholder' comment above for why we do this
if (node.value === 'history') {
flagSection(opts.sections, 'def')
}
fillSection(opts.sections, result)
if (node.value === 'history') {
flagSection(opts.sections, 'history')
}

return result
}

case 'each':
return renderIterator(node.value, node.children, opts)
case 'if': {
const result = renderCondition(node, node.children, opts)
fillSection(opts.sections, result)

if (node.value === 'system_prompt') {
flagSection(opts.sections, 'system')
}

case 'if':
return renderCondition(node, node.children, opts)
return result
}

case 'lowpriority':
return renderLowPriority(node, opts)
case 'lowpriority': {
const result = renderLowPriority(node, opts)
return result
}
}
}

Expand Down Expand Up @@ -715,3 +771,30 @@ function handleDice(node: DiceExpr) {
const rand = usable.reduce((p, c) => p + c, 0) + adjust
return rand
}

function fillSection(state: TemplateOpts['sections'], result: string | undefined) {
if (!state || !result) return
if (result === HISTORY_MARKER) return

if (!state.flags.system) {
state.sections.system.push(result)
return
}

if (!state.flags.def) {
state.sections.def.push(result)
return
}

if (!state.flags.history) {
state.sections.history.push(result)
}

state.sections.post.push(result)
}

function flagSection(state: TemplateOpts['sections'], section: Section) {
if (!state) return

state.flags[section] = true
}
5 changes: 5 additions & 0 deletions srv/adapter/gemini.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ModelAdapter } from './type'

export const handleGemini: ModelAdapter = async function* (opts) {}

// function toPayload(prompt: string) {}
1 change: 1 addition & 0 deletions srv/adapter/novel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ function getModernParams(gen: Partial<AppSchema.GenSettings>) {
top_k: gen.topK,
top_p: gen.topP,
top_a: gen.topA,
min_p: gen.minP ?? 0,
typical_p: gen.typicalP,
tail_free_sampling: gen.tailFreeSampling,
repetition_penalty: gen.repetitionPenalty,
Expand Down
2 changes: 1 addition & 1 deletion srv/db/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function mergeModelFormats(gen: AppSchema.UserGenPreset | null) {
if (!gen) return gen

if (gen.useAdvancedPrompt) {
gen.modelFormat = 'ChatML'
gen.modelFormat = gen.modelFormat || 'ChatML'
} else if (gen.promptOrderFormat && gen.promptOrderFormat in BUILTIN_FORMATS) {
gen.modelFormat = gen.promptOrderFormat as any
} else {
Expand Down
18 changes: 18 additions & 0 deletions tests/__snapshots__/placeholder.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,23 @@ Object {
"parsed": "OtherBot replies a lot
MainChar's personality: MainCharacter talks a lot",
"sections": Object {
"flags": Object {},
"sections": Object {
"def": Array [],
"history": Array [],
"post": Array [],
"system": Array [
"OtherBot replies a lot",
"
",
"MainChar's personality: MainCharacter talks a lot",
"OtherBot replies a lot
MainChar's personality: MainCharacter talks a lot",
],
},
},
}
`;
1 change: 1 addition & 0 deletions tests/prompt.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ This is how {{char}} should talk: {{example_dialogue}}`,
ultimeJailbreak: '!!UJB_PROMPT!!',
},
})
delete (actual.template as any).sections
expect(actual).to.matchSnapshot()
})

Expand Down
4 changes: 2 additions & 2 deletions web/pages/Chat/ChatDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { TitleCard } from '/web/shared/Card'
import { ChatGraphModal } from './components/GraphModal'
import { EVENTS, events } from '/web/emitter'
import { AppSchema } from '/common/types'
import { startTour } from '/web/tours'
import { canStartTour, startTour } from '/web/tours'

export { ChatDetail as default }

Expand Down Expand Up @@ -258,7 +258,7 @@ const ChatDetail: Component = () => {
return nav(`/chat/${chats.lastId}`)
}

if (charName) {
if (charName && canStartTour('chat')) {
settingStore.menu(true)
setTimeout(() => {
startTour('chat')
Expand Down
9 changes: 6 additions & 3 deletions web/pages/Settings/AISettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,14 @@ const AISettings: Component<{
export default AISettings

const ApiAccessHelp = neat`
The subscriber API endpoint uses the *OpenAI Text Completion* format.
The subscriber API endpoint uses the *OpenAI Text Completion* or *OpenAI Chat Completion* format.
The full URL for these endpoints are:
- https://api.agnai.chat/v1/completions
- https://api.agnai.chat/v1/chat/completions
**Instructions**:
1. Select your \`API Access Preset\`: This preset will be used for your API calls. Change this on your settings page.
2. Generate your API Key.
3. Use the API URL \`https://api.agnai.chat\` and your generated API key.
*SillyTavern*: Use _Ooba_ as the backend
`
17 changes: 16 additions & 1 deletion web/shared/PresetSettings/General.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { PhraseBias, StoppingStrings } from '../PhraseBias'
import { BUILTIN_FORMATS } from '/common/presets/templates'
import { getSubscriptionModelLimits } from '/common/util'
import { forms } from '/web/emitter'
import { Field, ContextSize, ModelFormat, ResponseLength, Temperature } from './Fields'
import { Field, ContextSize, ModelFormat, ResponseLength, Temperature, ThirdParty } from './Fields'

export const MODEL_FORMATS = Object.keys(BUILTIN_FORMATS).map((label) => ({ label, value: label }))

Expand Down Expand Up @@ -149,6 +149,8 @@ export const GeneralSettings: Field = (props) => {
</Show>

<Card hide={!serviceHasSetting(props.service, props.format, 'thirdPartyUrl')}>
<ThirdParty {...props} />

<div class="flex flex-wrap items-start gap-2">
<Toggle
fieldName="thirdPartyUrlNoSuffix"
Expand Down Expand Up @@ -308,6 +310,19 @@ export const GeneralSettings: Field = (props) => {

<Temperature {...props} />

<RangeInput
fieldName="minP"
label="Min P"
helperText="Used to discard tokens with the probability under a threshold (min_p) in the sampling process. Higher values will make text more predictable. (Put this value on 0 to disable its effect)"
min={0}
max={1}
step={0.01}
value={props.inherit?.minP ?? 0}
disabled={props.disabled}
aiSetting={'minP'}
recommended={props.sub?.preset.minP}
/>

<Toggle
fieldName="streamResponse"
label="Stream Response"
Expand Down
2 changes: 1 addition & 1 deletion web/shared/PresetSettings/Prompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export const PromptSettings: Field = (props) => {
disabled={props.disabled}
showHelp
inherit={props.inherit}
hide={useAdvanced() === 'basic'}
hide={useAdvanced() === 'basic' || props.mode === 'simple'}
showTemplates
/>

Expand Down
13 changes: 0 additions & 13 deletions web/shared/PresetSettings/Sliders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,6 @@ export const SliderSettings: Component<
aiSetting={'cfgScale'}
/>

<RangeInput
fieldName="minP"
label="Min P"
helperText="Used to discard tokens with the probability under a threshold (min_p) in the sampling process. Higher values will make text more predictable. (Put this value on 0 to disable its effect)"
min={0}
max={1}
step={0.01}
value={props.inherit?.minP ?? 0}
disabled={props.disabled}
aiSetting={'minP'}
recommended={props.sub?.preset.minP}
/>

<RangeInput
fieldName="topP"
label="Top P"
Expand Down
1 change: 1 addition & 0 deletions web/shared/PresetSettings/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export const ADAPTER_SETTINGS: {
tailFreeSampling: ['horde', 'novel', 'kobold', 'ooba', 'agnaistic', 'aphrodite', 'tabby'],
minP: [
'llamacpp',
'novel',
'kobold',
'koboldcpp',
'exllamav2',
Expand Down

0 comments on commit a596202

Please sign in to comment.