Skip to content

Commit 4a6ec0d

Browse files
authored
Sequence breakers (#1090)
- show all models in model select - sequence breakers
1 parent 3ab498d commit 4a6ec0d

File tree

6 files changed

+158
-27
lines changed

6 files changed

+158
-27
lines changed

common/valid/validate.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export function validateBody<T extends Validator>(
189189

190190
if (typeof value !== 'string') {
191191
errors.push(
192-
`.${prop} is ${typeof value}, expected undefined or literal of ${bodyType
192+
`.${prop} is ${typeof value} ('${value}'), expected undefined or literal of ${bodyType
193193
.filter((v) => v !== null)
194194
.join(' | ')}`
195195
)
@@ -198,7 +198,7 @@ export function validateBody<T extends Validator>(
198198

199199
if (bodyType.includes(value) === false) {
200200
errors.push(
201-
`.${prop} value is invalid, expected undefined or literal of ${bodyType
201+
`.${prop} value is invalid ('${value}'), expected undefined or literal of ${bodyType
202202
.filter((v) => v !== null)
203203
.join(' | ')}`
204204
)
@@ -209,12 +209,16 @@ export function validateBody<T extends Validator>(
209209
}
210210
if (isUnion(bodyType)) {
211211
if (typeof value !== 'string') {
212-
errors.push(`.${prop} is ${typeof value}, expected literal of ${bodyType.join(' | ')}`)
212+
errors.push(
213+
`.${prop} is ${typeof value} ('${value}'), expected literal of ${bodyType.join(' | ')}`
214+
)
213215
continue start
214216
}
215217

216218
if (bodyType.includes(value) === false) {
217-
errors.push(`.${prop} value is invalid, expected literal of ${bodyType.join(' | ')}`)
219+
errors.push(
220+
`.${prop} value is invalid ('${value}'), expected literal of ${bodyType.join(' | ')}`
221+
)
218222
continue start
219223
}
220224

srv/adapter/payloads.ts

+15-3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ function getBasePayload(opts: AdapterProps, stops: string[] = []) {
4444

4545
const json_schema = opts.jsonSchema ? toJsonSchema(opts.jsonSchema) : undefined
4646

47+
const characterNames = Object.values(opts.characters || {}).map((c) => c.name)
48+
const sequenceBreakers = Array.from(
49+
new Set([
50+
opts.char.name,
51+
opts.replyAs.name,
52+
...characterNames,
53+
...opts.members.map((m) => m.handle),
54+
]).values()
55+
)
56+
.concat(gen.drySequenceBreakers || [])
57+
.filter((t) => !!t)
58+
4759
if (!gen.temp) {
4860
gen.temp = 0.75
4961
}
@@ -110,7 +122,7 @@ function getBasePayload(opts: AdapterProps, stops: string[] = []) {
110122
dry_base: gen.dryBase,
111123
dry_allowed_length: gen.dryAllowedLength,
112124
dry_range: gen.dryRange,
113-
dry_sequence_breakers: gen.drySequenceBreakers,
125+
dry_sequence_breakers: sequenceBreakers,
114126
}
115127

116128
if (gen.dynatemp_range) {
@@ -293,7 +305,7 @@ function getBasePayload(opts: AdapterProps, stops: string[] = []) {
293305
dry_base: gen.dryBase,
294306
dry_allowed_length: gen.dryAllowedLength,
295307
dry_range: gen.dryRange,
296-
dry_sequence_breakers: gen.drySequenceBreakers,
308+
dry_sequence_breakers: sequenceBreakers,
297309
json_schema,
298310
}
299311

@@ -365,7 +377,7 @@ function getBasePayload(opts: AdapterProps, stops: string[] = []) {
365377
dry_base: gen.dryBase,
366378
dry_allowed_length: gen.dryAllowedLength,
367379
dry_range: gen.dryRange,
368-
dry_sequence_breakers: gen.drySequenceBreakers,
380+
dry_sequence_breakers: sequenceBreakers,
369381
}
370382

371383
if (gen.dynatemp_range) {

web/shared/CustomSelect.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import TextInput from './TextInput'
88
export type CustomOption = {
99
label: string | JSX.Element
1010
value: any
11+
disabled?: boolean
1112
}
1213

1314
export const CustomSelect: Component<{
@@ -134,9 +135,13 @@ const OptionList: Component<{
134135
<div
135136
classList={{
136137
'bg-[var(--hl-800)]': props.selected === option.value,
137-
'bg-700': props.selected !== option.value,
138+
'bg-700': !option.disabled && props.selected !== option.value,
139+
'bg-[var(--error-900)] text-700':
140+
option.disabled && props.selected !== option.value,
141+
'cursor-not-allowed': option.disabled,
142+
'cursor-pointer': !option.disabled,
138143
}}
139-
class={`w-full cursor-pointer gap-4 rounded-md px-2 py-1 text-sm`}
144+
class={`w-full gap-4 rounded-md px-2 py-1 text-sm`}
140145
onClick={() => props.onSelect(option)}
141146
>
142147
<div class="font-bold">{option.label}</div>

web/shared/PresetSettings/Agnaistic.tsx

+76-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import { Component, Show, createEffect, createMemo, createSignal, on } from 'sol
22
import { chatStore, presetStore, settingStore, userStore } from '/web/store'
33
import { CustomOption, CustomSelect } from '../CustomSelect'
44
import { getSubscriptionModelLimits } from '/common/util'
5-
import { SubscriptionModelLevel, SubscriptionModelOption } from '/common/types/presets'
5+
import {
6+
SubscriptionModelLevel,
7+
SubscriptionModelOption,
8+
SubscriptionTier,
9+
} from '/common/types/presets'
610
import { ChevronDown } from 'lucide-solid'
711
import { SubCTA } from '/web/Navigation'
812
import { applyStoreProperty, createEmitter } from '../util'
@@ -58,7 +62,16 @@ export const AgnaisticSettings: Field<{ noSave: boolean }> = (props) => {
5862
if (!opt) {
5963
return <div>None</div>
6064
}
61-
return <ModelLabel sub={opt?.sub!} limit={opt?.limit} nodesc />
65+
return (
66+
<ModelLabel
67+
sub={opt?.sub!}
68+
limit={opt?.limit}
69+
nodesc
70+
tier={opt.tierName}
71+
disabled={opt.disabled}
72+
requires={opt.requires}
73+
/>
74+
)
6275
})
6376

6477
return (
@@ -185,28 +198,66 @@ function useModelOptions() {
185198
const tierLevel = state.user?.admin ? Infinity : state.userLevel
186199
const level = state.user?.admin ? Infinity : tierLevel
187200

188-
return settings.config.subs
189-
.filter((sub) => (!!sub.preset.allowGuestUsage ? true : sub.level <= level))
190-
.map((sub) => {
191-
const limit = getSubscriptionModelLimits(sub.preset, level)
192-
193-
return {
194-
label: <ModelLabel sub={sub} limit={limit} />,
195-
value: sub._id,
196-
level: sub.level,
197-
sub,
198-
limit,
199-
}
200-
})
201-
.sort((l, r) => r.level - l.level)
201+
return (
202+
settings.config.subs
203+
.map((sub) => {
204+
const limit = getSubscriptionModelLimits(sub.preset, level)
205+
const disabled = !!sub.preset.allowGuestUsage ? false : sub.level > level
206+
const tier =
207+
sub.level <= 0
208+
? 'Free'
209+
: state.tiers.reduce<SubscriptionTier | null>((prev, curr) => {
210+
if (prev?.level === sub.level) return prev
211+
if (curr.level === sub.level) return curr
212+
if (curr.level < sub.level) return prev
213+
if (!prev) return curr
214+
215+
// Return the lowest tier above the threshold
216+
return prev.level > curr.level ? curr : prev
217+
}, null)?.name
218+
219+
const requires = sub.level <= 0 ? 'Registering' : tier || 'Staff Only'
220+
return {
221+
label: (
222+
<ModelLabel
223+
sub={sub}
224+
limit={limit}
225+
disabled={disabled}
226+
tier={tier || 'Staff'}
227+
requires={requires}
228+
/>
229+
),
230+
value: sub._id,
231+
level: sub.level,
232+
sub,
233+
limit,
234+
disabled,
235+
tierName: tier || 'Staff',
236+
requires,
237+
title: sub.name,
238+
}
239+
})
240+
// Remove staff models from the list
241+
.filter((sub) => (sub.tierName === 'Staff' && !state.user?.admin ? false : true))
242+
.sort((l, r) => {
243+
if (l.disabled && !r.disabled) return 1
244+
if (r.disabled && !l.disabled) return -1
245+
// if (l.disabled && r.disabled) return l.title.localeCompare(r.title)
246+
if (l.level !== r.level) return l.level - r.level
247+
return l.title.localeCompare(r.title)
248+
})
249+
)
202250
})
203251

204252
return opts
205253
}
206254

207255
const ModelLabel: Component<{
208256
sub: SubscriptionModelOption
257+
tier: string
258+
requires: string
209259
limit?: SubscriptionModelLevel
260+
disabled: boolean
210261
nodesc?: boolean
211262
}> = (props) => {
212263
const context = createMemo(() =>
@@ -224,8 +275,15 @@ const ModelLabel: Component<{
224275
{Math.floor(context() / 1000)}K, {tokens()} tokens
225276
</div>
226277
</div>
227-
<Show when={props.sub.preset.description && !props.nodesc}>
228-
<div class="text-700 text-xs">{props.sub.preset.description}</div>
278+
<Show when={!props.disabled && !props.nodesc}>
279+
<div class="text-700 text-xs">
280+
{props.tier}
281+
{props.sub.preset.description ? ', ' : ''}
282+
{props.sub.preset.description}
283+
</div>
284+
</Show>
285+
<Show when={props.disabled}>
286+
<div class="text-700 text-xs">Requires {props.requires}</div>
229287
</Show>
230288
</div>
231289
)

web/store/user.ts

+12
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,23 @@ async function updateTheme(ui: UI.UISettings) {
867867

868868
const gradients = ui.bgCustomGradient ? getColorShades(ui.bgCustomGradient) : []
869869

870+
const notifies = Object.entries({
871+
info: 'sky',
872+
success: 'green',
873+
warning: 'premium',
874+
error: 'red',
875+
})
876+
870877
for (let shade = 100; shade <= 1000; shade += 100) {
871878
const index = shade / 100 - 1
872879
const num = ui.mode === 'light' ? 1000 - shade : shade
873880

874881
if (shade <= 900) {
882+
for (const [notify, source] of notifies) {
883+
const color = getRootVariable(`--${source}-${num}`)
884+
root.style.setProperty(`--${notify}-${num}`, color)
885+
}
886+
875887
const color = getRootVariable(`--${ui.theme}-${num}`)
876888
const colorRgb = hexToRgb(color)
877889
root.style.setProperty(`--hl-${shade}`, color)

web/variables.css

+40
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,46 @@
225225
--coolgray-900: #111827;
226226
--coolgray-1000: #0b111f;
227227

228+
--info-100: #e0f2fe;
229+
--info-200: #bae6fd;
230+
--info-300: #7dd3fc;
231+
--info-400: #38bdf8;
232+
--info-500: #0ea5e9;
233+
--info-600: #0284c7;
234+
--info-700: #0369a1;
235+
--info-800: #075985;
236+
--info-900: #0c4a6e;
237+
238+
--success-100: #dcfce7;
239+
--success-200: #bbf7d0;
240+
--success-300: #86efac;
241+
--success-400: #4ade80;
242+
--success-500: #22c55e;
243+
--success-600: #16a34a;
244+
--success-700: #15803d;
245+
--success-800: #166534;
246+
--success-900: #14532d;
247+
248+
--warning-100: #fef9c3;
249+
--warning-200: #fef08a;
250+
--warning-300: #fde047;
251+
--warning-400: #facc15;
252+
--warning-500: #eab308;
253+
--warning-600: #ca8a04;
254+
--warning-700: #a16207;
255+
--warning-800: #854d0e;
256+
--warning-900: #713f12;
257+
258+
--error-100: #fee2e2;
259+
--error-200: #fecaca;
260+
--error-300: #fca5a5;
261+
--error-400: #f87171;
262+
--error-500: #ef4444;
263+
--error-600: #dc2626;
264+
--error-700: #b91c1c;
265+
--error-800: #991b1b;
266+
--error-900: #7f1d1d;
267+
228268
--highlight: rgb(14 165 233);
229269

230270
--rgba-chat-bot: rgba(0, 0, 0);

0 commit comments

Comments
 (0)