Skip to content

Commit 65db667

Browse files
authored
Post deployment fixes III (#1065)
* fix greeting updating * fix char persona token counting - fix chat rename - fix infinite loop on preset pane open - chat override persona switching improvements * remove id from create new book * fix edit book desc * Display claude model for 3rd party + claude * allow claude url from preset
1 parent 1f526ba commit 65db667

13 files changed

+108
-44
lines changed

srv/adapter/claude.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { CLAUDE_CHAT_MODELS, OPENAI_MODELS } from '/common/adapters'
1919
import { toChatCompletionPayload } from './chat-completion'
2020
import { sendOne } from '../api/ws'
2121
import { sanitiseAndTrim } from '/common/requests/util'
22+
import { GenSettings } from '/common/types/presets'
2223

2324
const CHAT_URL = `https://api.anthropic.com/v1/messages`
2425
const TEXT_URL = `https://api.anthropic.com/v1/complete`
@@ -50,8 +51,13 @@ const encoder = () => getTokenCounter('claude', '')
5051
export const handleClaude: ModelAdapter = async function* (opts) {
5152
const { members, user, log, guest, gen, isThirdParty } = opts
5253
const claudeModel = gen.claudeModel ?? defaultPresets.claude.claudeModel
53-
const base = getBaseUrl(user, claudeModel, isThirdParty)
54-
if (!user.claudeApiKey && !base.changed) {
54+
const base = getBaseUrl(user, gen, claudeModel, isThirdParty)
55+
56+
const hasKey = isThirdParty
57+
? !!(gen.thirdPartyKey || user.thirdPartyPassword)
58+
: !!user.claudeApiKey
59+
60+
if (!hasKey && !base.changed) {
5561
yield { error: `Claude request failed: Claude API key not set. Check your settings.` }
5662
return
5763
}
@@ -147,9 +153,15 @@ export const handleClaude: ModelAdapter = async function* (opts) {
147153
}
148154
}
149155

150-
function getBaseUrl(user: AppSchema.User, model: string, isThirdParty?: boolean) {
151-
if (isThirdParty && user.thirdPartyFormat === 'claude' && user.koboldUrl) {
152-
return { url: user.koboldUrl, changed: true }
156+
function getBaseUrl(
157+
user: AppSchema.User,
158+
gen: Partial<GenSettings>,
159+
model: string,
160+
isThirdParty?: boolean
161+
) {
162+
if (isThirdParty && user.thirdPartyFormat === 'claude') {
163+
const url = gen.thirdPartyUrl || user.koboldUrl
164+
return { url, changed: true }
153165
}
154166

155167
if (CLAUDE_CHAT_MODELS[model]) {

web/pages/Character/CreateCharacterForm.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ export const CreateCharacterForm: Component<{
499499
"E.g. *I smile as you walk into the room* Hello, {{user}}! I can't believe it's lunch time already! Where are we going?"
500500
}
501501
value={editor.state.greeting}
502+
onChange={(ev) => editor.update('greeting', ev.currentTarget.value)}
502503
class="h-60"
503504
tokenCount={(v) => setTokens((prev) => ({ ...prev, greeting: v }))}
504505
/>

web/pages/Character/form/AltGreetings.tsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, For } from 'solid-js'
1+
import { Component, Index } from 'solid-js'
22
import TextInput from '/web/shared/TextInput'
33
import { MinusCircle, Plus } from 'lucide-solid'
44
import Button from '/web/shared/Button'
@@ -20,23 +20,23 @@ export const AlternateGreetingsInput: Component<{
2020

2121
return (
2222
<>
23-
<For each={props.greetings}>
23+
<Index each={props.greetings}>
2424
{(altGreeting, i) => (
2525
<div class="flex gap-2">
2626
<TextInput
2727
isMultiline
28-
fieldName={`alternateGreeting${i() + 1}`}
28+
fieldName={`alternateGreeting${i + 1}`}
2929
placeholder="An alternate greeting for your character"
30-
value={altGreeting}
31-
onChange={(ev) => onChange(ev, i())}
30+
value={altGreeting()}
31+
onChange={(ev) => onChange(ev, i)}
3232
parentClass="w-full"
3333
/>
34-
<div class="1/12 flex items-center" onClick={() => removeGreeting(i())}>
34+
<div class="1/12 flex items-center" onClick={() => removeGreeting(i)}>
3535
<MinusCircle size={16} class="focusable-icon-button" />
3636
</div>
3737
</div>
3838
)}
39-
</For>
39+
</Index>
4040
<div>
4141
<Button onClick={addGreeting}>
4242
<Plus size={16} />

web/pages/Chat/ChatSettings.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ const ChatSettings: Component<{
192192
</Show>
193193
<Card>
194194
<TextInput
195-
fieldName="name"
196195
class="text-sm"
197196
value={state.chat?.name}
197+
onChange={(ev) => setEdit('name', ev.currentTarget.value)}
198198
label={
199199
<>
200200
Chat name{' '}

web/pages/Chat/components/MemoryModal.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ const ChatMemoryModal: Component<{
137137
}}
138138
/>
139139
<div>
140-
<Button onClick={() => changeBook('new')}>Create New Memory Book {id()}</Button>
140+
<Button onClick={() => changeBook('new')}>Create New Memory Book</Button>
141141
</div>
142142

143143
<Divider />

web/pages/Memory/EditMemory.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const EditMemoryForm: Component<{
9090

9191
<TextInput
9292
label="Description"
93-
value={props.state.name}
93+
value={props.state.description}
9494
placeholder="(Optional) A description for your memory book"
9595
onChange={(e) => {
9696
props.setter({ description: e.currentTarget.value })

web/shared/Mode/ModeGenSettings.tsx

+11-6
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,17 @@ export const ModeGenSettings: Component<{
6666
)
6767
)
6868

69-
createEffect(() => {
70-
if (!props.presetId) return
71-
if (selected() !== props.presetId) {
72-
setSelected(props.presetId)
73-
}
74-
})
69+
createEffect(
70+
on(
71+
() => props.presetId,
72+
() => {
73+
if (!props.presetId) return
74+
if (selected() !== props.presetId) {
75+
setSelected(props.presetId)
76+
}
77+
}
78+
)
79+
)
7580

7681
const onSave = () => {
7782
const presetId = selected()

web/shared/PersonaAttributes.tsx

+61-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import { Plus, Trash, WandSparkles } from 'lucide-solid'
2-
import { Component, createMemo, createSignal, Index, onMount, Show } from 'solid-js'
2+
import {
3+
Component,
4+
createEffect,
5+
createMemo,
6+
createSignal,
7+
Index,
8+
on,
9+
onMount,
10+
Show,
11+
} from 'solid-js'
312
import Button from './Button'
413
import { FormLabel } from './FormLabel'
514
import TextInput from './TextInput'
@@ -8,6 +17,7 @@ import { formatCharacter } from '/common/characters'
817
import { AppSchema } from '/common/types'
918
import { CharEditor } from '../pages/Character/editor'
1019
import { SetStoreFunction } from 'solid-js/store'
20+
import { createDebounce } from './util'
1121

1222
type Attr = { key: string; values: string }
1323

@@ -34,13 +44,58 @@ const PersonaAttributes: Component<{
3444
const [tokens, setTokens] = createSignal(0)
3545

3646
onMount(() => {
37-
updateCount()
47+
countTokens()
3848
})
3949

50+
createEffect(
51+
on(
52+
() => props.state,
53+
(attrs) => {
54+
if (!attrs.length) return
55+
if (tokens()) return
56+
57+
countTokens()
58+
}
59+
)
60+
)
61+
62+
createEffect(
63+
on(
64+
() => props.schema,
65+
(kind, prev) => {
66+
// Convert the attributes to a text blob if switching from text -> attrs
67+
if (prev !== 'text' && kind === 'text') {
68+
let squished: string[] = []
69+
for (const { key, values } of props.state) {
70+
squished.push(`${key}:\n${values}`)
71+
}
72+
73+
props.setter([{ key: 'text', values: squished.join('\n\n') }].concat(props.state))
74+
}
75+
76+
// If we switch from text -> attrs, omit the 'text' attribute if it is the squished version from above
77+
if (kind !== 'text' && prev === 'text') {
78+
const text = props.state.find((s) => s.key === 'text')
79+
if (!text) return
80+
81+
let matching = true
82+
for (const { values } of props.state) {
83+
if (!text.values.includes(values)) matching = false
84+
break
85+
}
86+
87+
if (matching) {
88+
props.setter(props.state.filter((s) => s.key !== 'text'))
89+
}
90+
}
91+
}
92+
)
93+
)
94+
4095
const plainText = createMemo(() => props.schema === 'text')
4196

4297
const updateCount = async () => {
43-
if (!props.tokenCount || !props.form) return
98+
if (!props.tokenCount) return
4499
const attributes = fromAttrs(props.state)
45100

46101
const encoder = await getEncoder()
@@ -57,6 +112,8 @@ const PersonaAttributes: Component<{
57112
}
58113
}
59114

115+
const [countTokens] = createDebounce(updateCount, 1000)
116+
60117
const add = () => {
61118
const next = props.state.concat({ key: '', values: '' })
62119
props.setter(next)
@@ -75,6 +132,7 @@ const PersonaAttributes: Component<{
75132

76133
const next = props.state.map((a, i) => (i === index ? upd : a))
77134
props.setter(next)
135+
countTokens()
78136
}
79137

80138
return (

web/shared/PresetSettings/Agnaistic.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ export const AgnaisticSettings: Field<{ noSave: boolean }> = (props) => {
2525
() => ctx.preset?.registered?.agnaistic?.subscriptionId,
2626
(id) => {
2727
if (!id) return
28+
const curr = props.state.registered?.agnaistic?.subscriptionId
29+
if (id === curr) return
30+
2831
props.setter('registered', {
2932
...props.state.registered,
3033
agnaistic: {

web/shared/PresetSettings/General.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ export const GeneralSettings: Component<PresetTabProps> = (props) => {
258258
helperText="Which Claude model to use, models marked as 'Latest' will automatically switch when a new minor version is released."
259259
value={props.state.claudeModel ?? defaultPresets.claude.claudeModel}
260260
disabled={props.state.disabled}
261-
hide={hidePresetSetting(props.state, 'claudeModel')}
261+
hide={
262+
props.state.service === 'claude' ||
263+
(props.state.service === 'kobold' && props.state.thirdPartyFormat === 'claude')
264+
}
262265
onChange={(ev) => props.setter('claudeModel', ev.value)}
263266
/>
264267
<Show when={replicateModels().length > 1}>

web/shared/PresetSettings/Prompt.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export const PromptSettings: Component<PresetTabProps> = (props) => {
4545
characterId={jsonCharId()}
4646
presetId={props.state._id}
4747
update={(schema) => {
48-
console.log('changing schema', schema)
4948
props.setter('json', schema)
5049
}}
5150
inherit={props.state.json}

web/shared/PresetSettings/index.tsx

-13
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,6 @@ const PresetSettings: Component<
4343
return list
4444
})
4545

46-
createEffect(() => props.setter('pane', pane.showing()))
47-
createEffect(
48-
on(
49-
() => props.store,
50-
(inherited) => {
51-
if (inherited) {
52-
props.setter(inherited)
53-
}
54-
}
55-
)
56-
)
57-
5846
createEffect(
5947
on(
6048
() => (props.store.service || '') + services().length,
@@ -64,7 +52,6 @@ const PresetSettings: Component<
6452
if (!services().length) return
6553
if (props.store._id) return
6654

67-
console.log('new', services()[0].value)
6855
props.setter('service', services()[0].value as any)
6956
}
7057
)

web/shared/PresetSettings/types.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@ export type PresetTabProps = {
2222

2323
export type PresetState = Omit<AppSchema.SubscriptionModel, 'kind'> & {
2424
disabled?: boolean
25-
pane: boolean
2625
}
2726

2827
export type SetPresetState = SetStoreFunction<PresetState>
2928

3029
export function getPresetForm(state: PresetState) {
3130
const {
3231
disabled,
33-
pane,
3432
subApiKey,
3533
subDisabled,
3634
subLevel,
@@ -45,15 +43,14 @@ export function getPresetForm(state: PresetState) {
4543
}
4644

4745
export function getSubPresetForm(state: PresetState) {
48-
const { disabled, pane, ...form } = state
46+
const { disabled, ...form } = state
4947

5048
return { ...form, kind: 'subscription-setting' as const }
5149
}
5250

5351
export const initPreset: Omit<AppSchema.SubscriptionModel, 'kind'> & {
5452
userId: string
5553
disabled: boolean
56-
pane: boolean
5754
} = {
5855
_id: '',
5956
...agnaiPresets.agnai,
@@ -68,7 +65,6 @@ export const initPreset: Omit<AppSchema.SubscriptionModel, 'kind'> & {
6865
userId: '',
6966
allowGuestUsage: false,
7067
disabled: false,
71-
pane: false,
7268
}
7369

7470
export function getPresetEditor() {

0 commit comments

Comments
 (0)