import { useCallback, useEffect, useMemo, useState } from 'preact/hooks'; import styles from './header.module.css'; import { Connection, HORDE_ANON_KEY, isHordeConnection, isKoboldConnection, type IConnection, type IHordeModel } from '../../tools/connection'; import { Instruct } from '../../contexts/state'; import { useInputState } from '@common/hooks/useInputState'; import { useInputCallback } from '@common/hooks/useInputCallback'; import { Huggingface } from '../../tools/huggingface'; interface IProps { connection: IConnection; setConnection: (c: IConnection) => void; } export const ConnectionEditor = ({ connection, setConnection }: IProps) => { // kobold const [connectionUrl, setConnectionUrl] = useInputState(''); // horde const [apiKey, setApiKey] = useInputState(HORDE_ANON_KEY); const [modelName, setModelName] = useInputState(''); const [instruct, setInstruct] = useInputState(''); const [modelTemplate, setModelTemplate] = useInputState(''); const [hordeModels, setHordeModels] = useState([]); const [contextLength, setContextLength] = useState(0); const backendType = useMemo(() => { if (isKoboldConnection(connection)) return 'kobold'; if (isHordeConnection(connection)) return 'horde'; return 'unknown'; }, [connection]); const isOnline = useMemo(() => contextLength > 0, [contextLength]); useEffect(() => { setInstruct(connection.instruct); if (isKoboldConnection(connection)) { setConnectionUrl(connection.url); Connection.getContextLength(connection).then(setContextLength); } else if (isHordeConnection(connection)) { setModelName(connection.model); setApiKey(connection.apiKey || HORDE_ANON_KEY); Connection.getHordeModels() .then(m => setHordeModels(Array.from(m.values()).sort((a, b) => a.name.localeCompare(b.name)))); } }, [connection]); useEffect(() => { if (modelName) { Huggingface.findModelTemplate(modelName) .then(template => { if (template) { setModelTemplate(template); setInstruct(template); } }); } }, [modelName]); const setBackendType = useInputCallback((type) => { if (type === 'kobold') { setConnection({ instruct, url: connectionUrl, }); } else if (type === 'horde') { setConnection({ instruct, apiKey, model: modelName, }); } }, [setConnection, connectionUrl, apiKey, modelName, instruct]); const handleSetInstruct = useInputCallback((instruct: string) => { setConnection({...connection, instruct}); }, [setConnection, connection]); const handleBlurUrl = useCallback(() => { const regex = /^(?:http(s?):\/\/)?(.*?)\/?$/i; const url = connectionUrl.replace(regex, 'http$1://$2'); setConnection({ instruct, url, }); }, [connectionUrl, instruct, setConnection]); const handleBlurHorde = useCallback(() => { setConnection({ instruct, apiKey, model: modelName, }); }, [apiKey, modelName, instruct, setConnection]); return (
{isKoboldConnection(connection) && } {isHordeConnection(connection) && <> }
); };