Skip to content

Commit

Permalink
Fix/menu retraction (#1035)
Browse files Browse the repository at this point in the history
* open menu in canstart home tour
- auto-detect novelai max length
- fix bookname error when updating memory
* do not re-render sub-templates
  • Loading branch information
sceuick authored Sep 26, 2024
1 parent 031503f commit 52496fe
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 49 deletions.
105 changes: 67 additions & 38 deletions common/template-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ import peggy from 'peggy'
import { elapsedSince } from './util'
import { v4 } from 'uuid'

export type TemplateOpts = {
continue?: boolean
parts?: Partial<PromptParts>
chat: AppSchema.Chat

isPart?: boolean
isFinal?: boolean

char: AppSchema.Character
replyAs?: AppSchema.Character
impersonate?: AppSchema.Character
sender: AppSchema.Profile

lines?: string[]
characters?: Record<string, AppSchema.Character>
lastMessage?: string

chatEmbed?: Memory.UserEmbed<{ name: string }>[]
userEmbed?: Memory.UserEmbed[]

/** If present, history will be rendered last */
limit?: {
context: number
encoder: TokenCounter
output?: Record<string, { src: string; lines: string[] }>
}

/**
* Only allow repeatable placeholders. Excludes iterators, conditions, and prompt parts.
*/
repeatable?: boolean
inserts?: Map<number, string>
lowpriority?: Array<{ id: string; content: string }>

jsonValues: Record<string, any> | undefined
}

const parser = loadParser()

function loadParser() {
Expand Down Expand Up @@ -62,6 +99,21 @@ type HolderDefinition =
}
| { value: Holder }

const SAFE_PART_HOLDERS: { [key in Holder | 'roll']?: boolean } = {
char: true,
user: true,
chat_age: true,
value: true,
idle_duration: true,
random: true,
roll: true,
}

const FINAL_IGNORE_HOLDERS: { [key in Holder | 'roll']?: boolean } = {
system_prompt: true,
ujb: true,
}

type Holder =
| 'char'
| 'user'
Expand Down Expand Up @@ -103,40 +155,6 @@ type ChatEmbedProp = 'i' | 'name' | 'text'
type HistoryProp = 'i' | 'message' | 'dialogue' | 'name' | 'isuser' | 'isbot'
type BotsProp = 'i' | 'personality' | 'name'

export type TemplateOpts = {
continue?: boolean
parts?: Partial<PromptParts>
chat: AppSchema.Chat

char: AppSchema.Character
replyAs?: AppSchema.Character
impersonate?: AppSchema.Character
sender: AppSchema.Profile

lines?: string[]
characters?: Record<string, AppSchema.Character>
lastMessage?: string

chatEmbed?: Memory.UserEmbed<{ name: string }>[]
userEmbed?: Memory.UserEmbed[]

/** If present, history will be rendered last */
limit?: {
context: number
encoder: TokenCounter
output?: Record<string, { src: string; lines: string[] }>
}

/**
* Only allow repeatable placeholders. Excludes iterators, conditions, and prompt parts.
*/
repeatable?: boolean
inserts?: Map<number, string>
lowpriority?: Array<{ id: string; content: string }>

jsonValues: Record<string, any> | undefined
}

/**
* This function also returns inserts because Chat and Claude discard the
* parsed string and use the inserts for their own prompt builders
Expand All @@ -158,11 +176,11 @@ export async function parseTemplate(
const parts = opts.parts || {}

if (parts.systemPrompt) {
parts.systemPrompt = render(parts.systemPrompt, opts)
parts.systemPrompt = render(parts.systemPrompt, { ...opts, isPart: true })
}

if (parts.ujb) {
parts.ujb = render(parts.ujb, opts)
parts.ujb = render(parts.ujb, { ...opts, isPart: true })
}

const ast = parser.parse(template, {}) as PNode[]
Expand Down Expand Up @@ -214,7 +232,10 @@ export async function parseTemplate(
}
}

const result = render(output, opts).replace(/\r\n/g, '\n').replace(/\n\n+/g, '\n\n').trim()
const result = render(output, { ...opts, isFinal: true })
.replace(/\r\n/g, '\n')
.replace(/\n\n+/g, '\n\n')
.trim()
return {
parsed: result,
inserts: opts.inserts ?? new Map(),
Expand Down Expand Up @@ -450,7 +471,7 @@ function renderCondition(
const output: string[] = []
for (const child of children) {
if (typeof child !== 'string' && child.kind === 'else') continue
const result = renderNode(child, opts, value)
const result = renderNode(child, { ...opts, isPart: true }, value)
if (result) output.push(result)
}

Expand Down Expand Up @@ -567,6 +588,14 @@ function getPlaceholder(
return opts.jsonValues?.[name] || ''
}

if (opts.isPart && !SAFE_PART_HOLDERS[node.value]) {
return `{{${node.value}}}`
}

if (opts.isFinal && FINAL_IGNORE_HOLDERS[node.value]) {
return `{{${node.value}}}`
}

switch (node.value) {
case 'value':
return conditionText || ''
Expand Down
35 changes: 28 additions & 7 deletions srv/adapter/novel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,15 @@ export const handleNovel: ModelAdapter = async function* (opts) {
Authorization: `Bearer ${guest ? user.novelApiKey : decryptText(user.novelApiKey)}`,
}

const maxTokens = await getMaxTokens(body.model, headers)
if (maxTokens) {
body.parameters.max_length = Math.min(body.parameters.max_length, maxTokens)
}

const stream =
opts.kind !== 'summary' && opts.gen.streamResponse
? streamCompletion(headers, body, log)
: fullCompletition(headers, body, log)
: fullCompletion(headers, body, log)

let accum = ''
while (true) {
Expand Down Expand Up @@ -198,11 +203,6 @@ function getModernParams(gen: Partial<AppSchema.GenSettings>) {
mirostat_lr: gen.mirostatLR,
}

if (gen.cfgScale) {
payload.cfg_scale = gen.cfgScale
payload.cfg_uc = gen.cfgOppose || ''
}

return payload
}

Expand Down Expand Up @@ -252,7 +252,7 @@ const streamCompletion = async function* (headers: any, body: any, _log: AppLog)
return { text: tokens.join('') }
}

const fullCompletition = async function* (headers: any, body: any, log: AppLog) {
async function* fullCompletion(headers: any, body: any, log: AppLog) {
const res = await needle('post', novelUrl(body.model), body, {
json: true,
// timeout: 2000,
Expand Down Expand Up @@ -304,3 +304,24 @@ function getBaseUrl(model: string) {
if (url.toLowerCase().startsWith('http')) return url
return `https://${url}`
}

async function getMaxTokens(model: string, headers: any) {
try {
const config = await needle(
'get',
'https://api.novelai.net/user/subscription',
{},
{ json: true, headers, response_timeout: 5000 }
)

if (model !== 'llama-3-erato-v1' && model !== NOVEL_MODELS.kayra_v1) {
return
}

const tier = config.body?.tier ?? 0
if (tier !== 3) return 100
return 150
} catch (ex) {
return
}
}
4 changes: 3 additions & 1 deletion web/pages/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import WizardIcon from '/web/icons/WizardIcon'
import Slot from '/web/shared/Slot'
import { adaptersToOptions } from '/common/adapters'
import { useRef } from '/web/shared/hooks'
import { startTour } from '/web/tours'
import { canStartTour, startTour } from '/web/tours'

const enum Sub {
None,
Expand Down Expand Up @@ -60,6 +60,8 @@ const HomePage: Component = () => {
announceStore.getAll()

emitter.on('loaded', () => {
if (!canStartTour('home')) return
settingStore.menu(true)
startTour('home')
})
})
Expand Down
7 changes: 5 additions & 2 deletions web/pages/Memory/EditMemory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,10 @@ const EntryCard: Component<{

export function getBookUpdate(ref: Event | HTMLFormElement) {
const inputs = getFormEntries(ref)
const { name, description } = getStrictForm(ref, { name: 'string', description: 'string?' })
const { bookName = '', description } = getStrictForm(ref, {
bookName: 'string?',
description: 'string?',
})

const map = new Map<string, AppSchema.MemoryEntry>()

Expand Down Expand Up @@ -286,7 +289,7 @@ export function getBookUpdate(ref: Event | HTMLFormElement) {

const entries = Array.from(map.values())

const book = { name, description, entries }
const book = { name: bookName, description, entries }
return book
}

Expand Down
2 changes: 1 addition & 1 deletion web/store/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const initState: SettingState = {
guestAccessAllowed: canUseStorage(),
initLoading: true,
cfg: { loading: false, ttl: 0 },
showMenu: true,
showMenu: false,
showImpersonate: false,
models: [],
workers: [],
Expand Down

0 comments on commit 52496fe

Please sign in to comment.