Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/horde-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export async function generateImage(
onTick,
})

if (!image.text.startsWith('data:') && typeof window !== 'undefined') {
if (!image.text?.startsWith('data:') && typeof window !== 'undefined') {
image.text = `data:image/png;base64,${image.text}`
}

Expand Down
12 changes: 5 additions & 7 deletions common/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,9 @@ export async function createPromptParts(
const nextMsgs = opts.messages.slice()
for (let i = 0; i < nextMsgs.length; i++) {
if (nextMsgs[i].userId) continue
nextMsgs[i] = { ...nextMsgs[i], msg: trimSentence(nextMsgs[i].msg) || nextMsgs[i].msg }
const text = trimSentence(nextMsgs[i].msg) || nextMsgs[i].msg

nextMsgs[i] = { ...nextMsgs[i], msg: text }
}

opts.messages = nextMsgs
Expand Down Expand Up @@ -315,11 +317,7 @@ export type AssembledPrompt = Awaited<ReturnType<typeof assemblePrompt>>
* @param lines Always in time-ascending order (oldest to newest)
* @returns
*/
export async function assemblePrompt(
opts: GenerateRequestV2,
encoder: TokenCounter,
chat?: boolean
) {
export async function assemblePrompt(opts: GenerateRequestV2, encoder: TokenCounter) {
const post = createPostPrompt(opts)
const template = getTemplate(opts)

Expand Down Expand Up @@ -558,7 +556,7 @@ export async function buildPromptPlaceholders(
const temp = opts.chat.tempCharacters?.[bot._id]
if (temp?.deletedAt || temp?.favorite === false) continue

if (!bot._id.startsWith('temp-') && !chat.characters?.[bot._id]) {
if (!bot._id?.startsWith('temp-') && !chat.characters?.[bot._id]) {
continue
}

Expand Down
47 changes: 33 additions & 14 deletions common/reasoning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,25 @@ export function extractReasoning(

if (!open || !close) return { thoughts: [], content }

const len = {
open: open.length,
close: close.length,
}

const thoughts: string[] = []

if (!content) return { thoughts, content }

const init = {
start: content.indexOf(open),
end: content.indexOf(close),
open,
close,
}

if (init.start === -1 && open !== defaults.open) {
init.start = content.indexOf(defaults.open)
init.open = defaults.open
}

if (init.end === -1 && close !== defaults.close) {
init.end = content.indexOf(defaults.close)
init.close = defaults.close
}

// No thoughts, skip everything
Expand All @@ -50,20 +57,32 @@ export function extractReasoning(
let start = content.indexOf(open)
let end = content.indexOf(close)

if (open !== defaults.open) start = content.indexOf(defaults.open)
if (close !== defaults.close) end = content.indexOf(defaults.close)
const used = {
start: open,
end: close,
}

if (open !== defaults.open && start === -1) {
start = content.indexOf(defaults.open)
used.start = defaults.open
}

if (close !== defaults.close && end === -1) {
end = content.indexOf(defaults.close)
used.end = defaults.close
}

// Both present, but end comes before start
if (start > -1 && end > -1 && start > end) {
let pre = content.slice(0, end)

let thought = content.slice(start + len.open)
const nextEnd = thought.indexOf(close)
let thought = content.slice(start + used.start.length)
const nextEnd = thought.indexOf(used.end)

// There is another end tag
if (nextEnd > -1) {
const innerThought = thought.slice(0, nextEnd)
const post = thought.slice(nextEnd + len.close)
const post = thought.slice(nextEnd + used.end.length)
content = `${pre.trim()}\n${post.trim()}`
thought = innerThought
thoughts.push(thought)
Expand All @@ -77,8 +96,8 @@ export function extractReasoning(
// Both tags present
if (start > -1 && end > -1) {
const pre = content.slice(0, start)
const post = content.slice(end + len.close)
const thought = content.slice(start + len.open, end)
const post = content.slice(end + used.end.length)
const thought = content.slice(start + used.start.length, end)
thoughts.push(thought)

// Case 1. Only display pre-thought text
Expand All @@ -102,7 +121,7 @@ export function extractReasoning(
// Only opening tag
if (start > -1) {
const pre = content.slice(0, start)
const thought = content.slice(start + len.open)
const thought = content.slice(start + used.start.length)

content = pre
thoughts.push(thought)
Expand All @@ -111,7 +130,7 @@ export function extractReasoning(

// Only closing tag
if (end > -1) {
const post = content.slice(end + len.close)
const post = content.slice(end + used.end.length)
const thought = content.slice(0, end)
thoughts.push(thought)
content = post
Expand Down
2 changes: 1 addition & 1 deletion common/requests/swarmui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ async function getPayload(req: ImageRequestOpts) {

function getUrl(opts: { host?: string; path: string; getter?: boolean }) {
const affix = opts.getter ? '' : '/API'
const prefix = opts.path.startsWith('/') ? affix : `${affix}/`
const prefix = opts.path?.startsWith('/') ? affix : `${affix}/`
const host = opts.host || 'http://localhost:7801'

return `${host}${prefix}${opts.path}`
Expand Down
2 changes: 1 addition & 1 deletion common/requests/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function joinUrl(base: string, path: string) {
base = base.slice(0, -1)
}

if (path.startsWith('/')) {
if (path?.startsWith('/')) {
path = path.slice(1)
}

Expand Down
4 changes: 2 additions & 2 deletions common/scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ const eventTypes: Record<AppSchema.ScenarioEventType, boolean> = {

export function isScenarioEvent(event?: any): event is AppSchema.ScenarioEventType {
if (typeof event !== 'string') return false
if (!event.startsWith('send-event:')) return false
if (!event?.startsWith('send-event:')) return false

const [, type] = event.split(':')
return !!eventTypes[type as AppSchema.ScenarioEventType]
}

export function getScenarioEventType(event: string): AppSchema.ScenarioEventType | undefined {
if (!event.startsWith('send-event')) return
if (!event?.startsWith('send-event')) return

const [, type] = event.split(':') as AppSchema.ScenarioEventType[]

Expand Down
2 changes: 1 addition & 1 deletion common/template-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { findLast } from './util'
import { GenerateRequestV2 } from '/srv/adapter/type'

export async function toChatMessages(req: GenerateRequestV2, counter: TokenCounter) {
const assembled = await assemblePrompt(req, counter, true)
const assembled = await assemblePrompt(req, counter)

const { sections } = assembled
const {
Expand Down
8 changes: 4 additions & 4 deletions common/template-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,10 +806,10 @@ function getEntities(holder: IterableHolder, opts: TemplateOpts) {
if (char.deletedAt) continue

// Exclude temp characters that have been disabled/removed
if (char._id.startsWith('temp-') && char.favorite === false) continue
if (char._id?.startsWith('temp-') && char.favorite === false) continue

// Exclude non-temp characters that have been removed from the chat
if (!char._id.startsWith('temp-') && !opts.chat?.characters?.[char._id]) continue
if (!char._id?.startsWith('temp-') && !opts.chat?.characters?.[char._id]) continue
chars.push(char)
}
return chars
Expand Down Expand Up @@ -951,7 +951,7 @@ function getPlaceholder(
) {
if (opts.repeatable && !repeatableHolders.has(node.value as any)) return ''

if (node.value.startsWith('json.')) {
if (node.value?.startsWith('json.')) {
const target = node.value.replace('json.', '')

const jsonValues = opts.jsonValues || opts.history?.slice(-1)[0]?.json || {}
Expand All @@ -960,7 +960,7 @@ function getPlaceholder(
return value
}

if (node.value.startsWith('var.') || node.value.startsWith('vars.')) {
if (node.value?.startsWith('var.') || node.value?.startsWith('vars.')) {
const name = node.value.replace('var.', '').replace('vars.', '')
return opts.parts?.props?.[name] || ''
}
Expand Down
33 changes: 29 additions & 4 deletions common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,34 @@ import type { GenerateRequestV2 } from '/srv/adapter/type'

export const PING_INTERVAL_MS = 30000

export function stopResponse(opts: { text: string; author: string; stops: string[] }) {
let generated = opts.text

if (opts.author) {
generated = generated.split(`${opts.author}:`).join('').trim()
}

let index = -1
let trimmed = opts.stops.reduce((prev, endToken) => {
const idx = generated.indexOf(endToken)

if (idx === -1) return prev

const text = generated.slice(0, idx)
if (index === -1 || idx < index) {
index = idx
return text
}

return prev
}, '')

return trimmed || generated
}

// this is an edited and inverted ver of https://stackoverflow.com/a/70385497
export function incompleteJson(data: string) {
if (data.startsWith('{') && !data.endsWith('}')) return true
if (data?.startsWith('{') && !data.endsWith('}')) return true
try {
const parsed = JSON.parse(data)
if (parsed && typeof parsed === 'object') {
Expand Down Expand Up @@ -53,7 +78,7 @@ export function parseEvent(msg: string) {

export function getMimeTypeBase64(base64: string) {
const [start, encode] = base64.split(';')
if (!start.startsWith('data:')) return { mimeType: 'image/jpeg', data: base64 }
if (!start?.startsWith('data:')) return { mimeType: 'image/jpeg', data: base64 }

return { mimeType: start.slice(5), data: encode.replace('base64,', '') }
}
Expand Down Expand Up @@ -195,7 +220,7 @@ export function toDuration(valueSecs: number, full?: boolean) {

if (full) {
return [`${days}d`, `${hours}h`, `${minutes}m`, `${seconds}s`]
.filter((time) => !time.startsWith('0'))
.filter((time) => !time?.startsWith('0'))
.join(':')
}

Expand Down Expand Up @@ -394,7 +419,7 @@ export function getBotName(
const charId = msg.characterId || ''
if (!charId) return replyAs?.name || main.name

if (charId.startsWith('temp-')) {
if (charId?.startsWith('temp-')) {
const temp = chat.tempCharacters?.[charId]
if (!temp) return main.name
return temp.name
Expand Down
4 changes: 2 additions & 2 deletions srv/adapter/agnaistic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,13 @@ export const handleAgnaistic: ModelAdapter = async function* (opts) {

body.api_key = key

const stripped = body.messages ? stripImageContent(body.messages) : null
const stripped = body.messages?.length ? stripImageContent(body.messages) : null

yield { prompt: stripped || prompt }

log.debug({ ...body, prompt: null, messages: null, imageData: null }, 'Agnaistic payload')

log.debug(`Prompt:\n${body.messages ? JSON.stringify(stripped, null, 2) : prompt}`)
log.debug(`Prompt:\n${body.messages?.length ? JSON.stringify(stripped, null, 2) : prompt}`)

const [submodel, override = ''] = subPreset.subModel.split(',')

Expand Down
Loading
Loading