Skip to content

Commit 4289653

Browse files
authored
'Fixes and improvements' (#972)
1 parent 437df2e commit 4289653

File tree

97 files changed

+2314
-531
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+2314
-531
lines changed

.vscode/launch.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"version": "0.2.0",
66
"configurations": [
77
{
8-
"name": "Launch API",
8+
"name": "Launch API + Watch",
99
"program": "${workspaceFolder}/srv/start.ts",
1010
"request": "launch",
1111
"sourceMaps": true,
@@ -14,6 +14,15 @@
1414
"console": "integratedTerminal",
1515
"preLaunchTask": "build server"
1616
},
17+
{
18+
"name": "Launch API",
19+
"program": "${workspaceFolder}/srv/start.ts",
20+
"request": "launch",
21+
"sourceMaps": true,
22+
"skipFiles": ["<node_internals>/**"],
23+
"type": "node",
24+
"console": "integratedTerminal"
25+
},
1726
{
1827
"name": "Attach",
1928
"port": 9229,

common/adapters.ts

+13-140
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { AppSchema } from './types/schema'
22

3-
export type AIAdapter = (typeof AI_ADAPTERS)[number]
4-
export type ChatAdapter = (typeof CHAT_ADAPTERS)[number]
5-
export type PersonaFormat = (typeof PERSONA_FORMATS)[number]
6-
export type ThirdPartyFormat = (typeof THIRDPARTY_FORMATS)[number]
7-
83
export type AdapterSetting = {
94
/** The name of the field within the settings object */
105
field: string
@@ -48,6 +43,12 @@ export const PERSONA_LABELS: { [key in PersonaFormat]: string } = {
4843
text: 'Plain Text',
4944
}
5045

46+
export const JSON_SCHEMA_SUPPORTED: { [key in AIAdapter | ThirdPartyFormat]?: boolean } = {
47+
agnaistic: true,
48+
llamacpp: true,
49+
tabby: true,
50+
}
51+
5152
export const THIRDPARTY_HANDLERS: { [svc in ThirdPartyFormat]: AIAdapter } = {
5253
openai: 'openai',
5354
'openai-chat': 'openai',
@@ -337,141 +338,8 @@ export const samplerDisableValues: { [key in keyof PresetAISettings]?: number }
337338
tailFreeSampling: 1,
338339
}
339340

340-
export const adapterSettings: {
341-
[key in keyof PresetAISettings]: Array<AIAdapter | ThirdPartyFormat>
342-
} = {
343-
temp: [
344-
'kobold',
345-
'novel',
346-
'ooba',
347-
'horde',
348-
'openai',
349-
'scale',
350-
'claude',
351-
'goose',
352-
'agnaistic',
353-
'aphrodite',
354-
'tabby',
355-
'mistral',
356-
],
357-
tempLast: ['agnaistic', 'tabby', 'exllamav2'],
358-
dynatemp_range: ['kobold', 'ooba', 'tabby', 'agnaistic', 'aphrodite'],
359-
dynatemp_exponent: ['kobold', 'aphrodite', 'ooba', 'tabby', 'agnaistic'],
360-
smoothingFactor: ['kobold', 'aphrodite', 'ooba', 'tabby', 'agnaistic'],
361-
smoothingCurve: ['kobold', 'aphrodite'],
362-
maxTokens: AI_ADAPTERS.slice(),
363-
maxContextLength: AI_ADAPTERS.slice(),
364-
antiBond: ['openai', 'scale'],
365-
prefixNameAppend: ['openai', 'claude'],
366-
367-
swipesPerGeneration: ['aphrodite'],
368-
epsilonCutoff: ['aphrodite'],
369-
etaCutoff: ['aphrodite'],
370-
371-
prefill: ['claude'],
372-
373-
topP: [
374-
'horde',
375-
'kobold',
376-
'claude',
377-
'ooba',
378-
'openai',
379-
'novel',
380-
'agnaistic',
381-
'exllamav2',
382-
'openai-chat',
383-
'aphrodite',
384-
'tabby',
385-
'mistral',
386-
],
387-
repetitionPenalty: [
388-
'horde',
389-
'novel',
390-
'kobold',
391-
'ooba',
392-
'agnaistic',
393-
'exllamav2',
394-
'aphrodite',
395-
'tabby',
396-
],
397-
repetitionPenaltyRange: ['horde', 'novel', 'kobold', 'ooba', 'agnaistic', 'tabby'],
398-
repetitionPenaltySlope: ['horde', 'novel', 'kobold'],
399-
tailFreeSampling: ['horde', 'novel', 'kobold', 'ooba', 'agnaistic', 'aphrodite', 'tabby'],
400-
minP: ['llamacpp', 'kobold', 'koboldcpp', 'exllamav2', 'ooba', 'agnaistic', 'aphrodite', 'tabby'],
401-
topA: ['horde', 'novel', 'kobold', 'ooba', 'agnaistic', 'aphrodite', 'tabby'],
402-
topK: [
403-
'horde',
404-
'novel',
405-
'kobold',
406-
'ooba',
407-
'claude',
408-
'agnaistic',
409-
'exllamav2',
410-
'aphrodite',
411-
'tabby',
412-
],
413-
typicalP: ['horde', 'novel', 'kobold', 'ooba', 'agnaistic', 'exllamav2', 'aphrodite', 'tabby'],
414-
415-
mirostatToggle: ['aphrodite', 'tabby'],
416-
mirostatLR: ['novel', 'ooba', 'agnaistic', 'llamacpp', 'aphrodite', 'tabby'],
417-
mirostatTau: ['novel', 'ooba', 'agnaistic', 'llamacpp', 'aphrodite', 'tabby'],
418-
cfgScale: ['novel', 'ooba', 'tabby'],
419-
cfgOppose: ['novel', 'ooba', 'tabby'],
420-
phraseRepPenalty: ['novel'],
421-
phraseBias: ['novel'],
422-
423-
thirdPartyUrl: ['kobold', 'ooba'],
424-
thirdPartyFormat: ['kobold'],
425-
thirdPartyModel: ['openai', 'openai-chat', 'aphrodite', 'tabby'],
426-
thirdPartyKey: ['kobold', 'aphrodite', 'tabby', 'openai', 'openai-chat'],
427-
428-
claudeModel: ['claude'],
429-
novelModel: ['novel'],
430-
mistralModel: ['mistral'],
431-
oaiModel: ['openai', 'openai-chat'],
432-
frequencyPenalty: ['openai', 'kobold', 'novel', 'agnaistic', 'openai-chat', 'aphrodite', 'tabby'],
433-
presencePenalty: ['openai', 'kobold', 'novel', 'openai-chat', 'aphrodite', 'tabby'],
434-
streamResponse: [
435-
'openai',
436-
'kobold',
437-
'novel',
438-
'claude',
439-
'ooba',
440-
'agnaistic',
441-
'openai-chat',
442-
'aphrodite',
443-
'tabby',
444-
'mistral',
445-
],
446-
openRouterModel: ['openrouter'],
447-
stopSequences: [
448-
'ooba',
449-
'agnaistic',
450-
'novel',
451-
'mancer',
452-
'llamacpp',
453-
'horde',
454-
'exllamav2',
455-
'kobold',
456-
'aphrodite',
457-
'tabby',
458-
],
459-
trimStop: ['koboldcpp'],
460-
461-
addBosToken: ['ooba', 'agnaistic', 'tabby'],
462-
banEosToken: ['ooba', 'aphrodite', 'tabby'],
463-
tokenHealing: ['agnaistic', 'exllamav2', 'ooba', 'tabby'],
464-
doSample: ['ooba'],
465-
encoderRepitionPenalty: ['ooba'],
466-
penaltyAlpha: ['ooba'],
467-
earlyStopping: ['ooba'],
468-
numBeams: ['ooba'],
469-
470-
replicateModelName: ['replicate'],
471-
replicateModelVersion: ['replicate'],
472-
replicateModelType: ['replicate'],
473-
474-
skipSpecialTokens: ['ooba', 'kobold'],
341+
export function adaptersToOptions(adapters: AIAdapter[]) {
342+
return adapters.map((adp) => ({ label: ADAPTER_LABELS[adp], value: adp }))
475343
}
476344

477345
export type RegisteredAdapter = {
@@ -552,3 +420,8 @@ export const samplerOrders: { [key in AIAdapter]?: Array<keyof PresetAISettings>
552420
'mirostatTau',
553421
],
554422
}
423+
424+
export type AIAdapter = (typeof AI_ADAPTERS)[number]
425+
export type ChatAdapter = (typeof CHAT_ADAPTERS)[number]
426+
export type PersonaFormat = (typeof PERSONA_FORMATS)[number]
427+
export type ThirdPartyFormat = (typeof THIRDPARTY_FORMATS)[number]

common/presets/templates.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,12 @@ Write {{char}}'s next reply in a fictional roleplay chat between {{user}} and {{
252252
{{/if}}
253253
Then the roleplay chat begins.<|im_end|>
254254
255-
{{#each msg}}{{#if .isbot}}<|im_start|>assistant{{/if}}{{#if .isuser}}<|im_start|>user{{/if}}
256-
{{.name}}: {{.msg}}<|im_end|>
255+
{{#each msg}}<|im_start|>[{{.name}}]
256+
{{.msg}}<|im_end|>
257257
{{/each}}
258258
{{#if ujb}}<|im_start|>system
259259
{{ujb}}<|im_end|>
260260
{{/if}}
261-
<|im_start|>assistant
261+
<|im_start|>[{{char}}]
262262
{{post}}`,
263263
}

common/prompt-order.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,9 @@ export const formatHolders: Record<string, Record<string, string>> = {
9595
history: neat`<|im_start|>system
9696
Then the roleplay chat between {{user}} and {{char}} begins.<|im_end|>
9797
98-
{{#each msg}}{{#if .isbot}}<|im_start|>assistant{{/if}}{{#if .isuser}}<|im_start|>user{{/if}}
99-
{{.name}}: {{.msg}}<|im_end|>
100-
{{/each}}`,
101-
post: neat`<|im_start|>assistant
98+
{{#each msg}}<|im_start|>{{#if .isbot}}assistant{{/if}}{{#if .isuser}}user{{/if}}
99+
{{.name}}: {{.msg}}<|im_end|>{{/each}}`,
100+
post: neat`POST<|im_start|>assistant
102101
{{post}}`,
103102
system_prompt: neat`{{#if system_prompt}}<|im_start|>system
104103
{{system_prompt}}<|im_end|>{{/if}}`,

common/prompt.ts

+44-6
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ export type BuildPromptOpts = {
8989
}
9090

9191
/** {{user}}, <user>, {{char}}, <bot>, case insensitive */
92-
export const BOT_REPLACE = /(\{\{char\}\}|<BOT>|\{\{name\}\})/gi
93-
export const SELF_REPLACE = /(\{\{user\}\}|<USER>)/gi
92+
export const BOT_REPLACE = /(\{\{char\}\}|\{\{name\}\})/gi
93+
export const SELF_REPLACE = /(\{\{user\}\})/gi
9494
export const START_REPLACE = /(<START>)/gi
9595

9696
const HOLDER_NAMES = {
@@ -159,8 +159,13 @@ export async function createPromptParts(opts: PromptOpts, encoder: TokenCounter)
159159
/**
160160
* The lines from `getLinesForPrompt` are returned in time-descending order
161161
*/
162-
const template = getTemplate(opts)
162+
let template = getTemplate(opts)
163163
const templateSize = await encoder(template)
164+
165+
if (opts.modelFormat) {
166+
template = replaceTags(template, opts.modelFormat)
167+
}
168+
164169
/**
165170
* It's important for us to pass in a max context that is _realistic-ish_ as the embeddings
166171
* are retrieved based on the number of history messages we return here.
@@ -237,12 +242,11 @@ export function getTemplate(opts: Pick<GenerateRequestV2, 'settings' | 'chat'>)
237242

238243
const template = opts.settings?.gaslight || fallback?.gaslight || defaultTemplate
239244

240-
const validate = opts.settings?.useAdvancedPrompt !== 'no-validation'
241-
242-
if (!validate) {
245+
if (opts.settings?.useAdvancedPrompt === 'no-validation') {
243246
return template
244247
}
245248

249+
// Deprecated
246250
return ensureValidTemplate(template)
247251
}
248252

@@ -909,3 +913,37 @@ export function resolveScenario(
909913

910914
return result.trim()
911915
}
916+
917+
type JsonType =
918+
| { type: 'string'; title?: string; maxLength?: number }
919+
| { type: 'integer'; title?: string }
920+
| { type: 'enum'; enum: string[]; title?: string }
921+
922+
type JsonSchema = {
923+
title: string
924+
type: 'object'
925+
properties: Record<string, JsonType>
926+
}
927+
928+
export const schema = {
929+
str: (title?: string, maxLength?: number) => ({ type: 'string', title, maxLength }),
930+
int: (title?: string) => ({ type: 'integer', title }),
931+
enum: (values: string[], title?: string) => ({ type: 'enum', enum: values, title }),
932+
} satisfies Record<string, (...args: any[]) => JsonType>
933+
934+
export function toJsonSchema(body: Record<string, JsonType>): JsonSchema {
935+
const schema: JsonSchema = {
936+
title: 'Response',
937+
type: 'object',
938+
properties: {},
939+
}
940+
941+
const props: JsonSchema['properties'] = {}
942+
943+
for (const [key, def] of Object.entries(body)) {
944+
props[key] = def
945+
}
946+
947+
schema.properties = props
948+
return schema
949+
}

common/template-parser.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ function loadParser() {
2222
}
2323
}
2424

25+
const HISTORY_MARKER = '__history__marker__'
26+
2527
type PNode = PlaceHolder | ConditionNode | IteratorNode | InsertNode | LowPriorityNode | string
2628

2729
type PlaceHolder = { kind: 'placeholder'; value: Holder; values?: any; pipes?: string[] }
@@ -144,6 +146,14 @@ export async function parseTemplate(
144146
let unusedTokens = 0
145147
let linesAddedCount = 0
146148

149+
/** Remove everything after history to attempt to perform a 'continue' */
150+
if (opts.continue && output.includes(HISTORY_MARKER)) {
151+
const index = output.indexOf(HISTORY_MARKER)
152+
if (index > -1) {
153+
output = output.slice(0, index + HISTORY_MARKER.length)
154+
}
155+
}
156+
147157
/** Replace iterators */
148158
if (opts.limit && opts.limit.output) {
149159
for (const [id, { lines, src }] of Object.entries(opts.limit.output)) {
@@ -177,7 +187,7 @@ export async function parseTemplate(
177187
}
178188
}
179189

180-
const result = render(output, opts).replace(/\r\n/g, '\n').replace(/\n\n+/g, '\n\n').trimStart()
190+
const result = render(output, opts).replace(/\r\n/g, '\n').replace(/\n\n+/g, '\n\n').trim()
181191
return {
182192
parsed: result,
183193
inserts: opts.inserts ?? new Map(),
@@ -479,7 +489,7 @@ function renderIterator(holder: IterableHolder, children: CNode[], opts: Templat
479489
}
480490

481491
if (isHistory && opts.limit?.output) {
482-
const id = '__' + v4() + '__'
492+
const id = HISTORY_MARKER
483493
opts.limit.output[id] = { src: holder, lines: output }
484494
return id
485495
}

common/types/schema.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ export namespace AppSchema {
7979
imagesHost: string
8080
imagesModels: ImageModel[]
8181

82-
ttsEnabled: boolean
8382
ttsHost: string
83+
ttsApiKey: string
84+
ttsAccess: 'off' | 'users' | 'subscribers' | 'admins'
8485

8586
maxGuidanceTokens: number
8687
maxGuidanceVariables: number
@@ -173,6 +174,8 @@ export namespace AppSchema {
173174
/** @todo remove after next deployment */
174175
tier?: AppSchema.SubscriptionTier
175176
serverConfig?: Configuration
177+
178+
googleClientId: string | undefined
176179
}
177180

178181
export type ChatMode = 'standard' | 'adventure'
@@ -289,6 +292,11 @@ export namespace AppSchema {
289292
}
290293
}
291294

295+
google?: {
296+
sub: any
297+
email: any
298+
}
299+
292300
billing?: {
293301
status: 'active' | 'cancelled'
294302
cancelling?: boolean

0 commit comments

Comments
 (0)