Compare commits
No commits in common. "df46bdafe40476068390dbfd0b258c524419390f" and "ce67d072697af7049a7874d23bb878fba65cac6d" have entirely different histories.
df46bdafe4
...
ce67d07269
|
|
@ -2,11 +2,9 @@ import { Header } from "./header/header";
|
||||||
import { Chat } from "./chat";
|
import { Chat } from "./chat";
|
||||||
import { Input } from "./input";
|
import { Input } from "./input";
|
||||||
|
|
||||||
import bgImage from '../assets/bg.jpg';
|
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
return (
|
return (
|
||||||
<div class='root' style={{ backgroundImage: `url('${bgImage.src}')` }}>
|
<div class='root'>
|
||||||
<div class='app'>
|
<div class='app'>
|
||||||
<Header />
|
<Header />
|
||||||
<Chat />
|
<Chat />
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ export const Message = ({ message, index, isLastUser, isLastAssistant }: IProps)
|
||||||
|
|
||||||
const content = swipe?.content;
|
const content = swipe?.content;
|
||||||
const summary = swipe?.summary;
|
const summary = swipe?.summary;
|
||||||
const cost = swipe?.cost ?? 0;
|
|
||||||
const htmlContent = useMemo(() => MessageTools.format(content ?? ''), [content]);
|
const htmlContent = useMemo(() => MessageTools.format(content ?? ''), [content]);
|
||||||
|
|
||||||
const handleEnableEdit = useCallback(() => {
|
const handleEnableEdit = useCallback(() => {
|
||||||
|
|
@ -33,10 +32,10 @@ export const Message = ({ message, index, isLastUser, isLastAssistant }: IProps)
|
||||||
}, [content]);
|
}, [content]);
|
||||||
|
|
||||||
const handleSaveEdit = useCallback(() => {
|
const handleSaveEdit = useCallback(() => {
|
||||||
editMessage(index, editedMessage.trim(), cost);
|
editMessage(index, editedMessage.trim());
|
||||||
editSummary(index, '', 0);
|
editSummary(index, '');
|
||||||
setEditing(false);
|
setEditing(false);
|
||||||
}, [editMessage, editSummary, index, editedMessage, cost]);
|
}, [editMessage, editSummary, index, editedMessage]);
|
||||||
|
|
||||||
const handleCancelEdit = useCallback(() => {
|
const handleCancelEdit = useCallback(() => {
|
||||||
setEditing(false);
|
setEditing(false);
|
||||||
|
|
@ -78,7 +77,6 @@ export const Message = ({ message, index, isLastUser, isLastAssistant }: IProps)
|
||||||
: <>
|
: <>
|
||||||
<div class={styles.text} dangerouslySetInnerHTML={{ __html: htmlContent }} ref={textRef} />
|
<div class={styles.text} dangerouslySetInnerHTML={{ __html: htmlContent }} ref={textRef} />
|
||||||
{summary && <small class={styles.summary}>{summary}</small>}
|
{summary && <small class={styles.summary}>{summary}</small>}
|
||||||
{cost > 0 && <small class={styles.summary}>💲 {cost}</small>}
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
<div class={styles.buttons}>
|
<div class={styles.buttons}>
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ const MESSAGES_TO_KEEP = 10;
|
||||||
|
|
||||||
interface IActions {
|
interface IActions {
|
||||||
compilePrompt: (messages: IMessage[], args?: ICompileArgs) => Promise<ICompiledPrompt>;
|
compilePrompt: (messages: IMessage[], args?: ICompileArgs) => Promise<ICompiledPrompt>;
|
||||||
generate: (prompt: string, extraSettings?: IGenerationSettings) => AsyncGenerator<Connection.TextChunk>;
|
generate: (prompt: string, extraSettings?: IGenerationSettings) => AsyncGenerator<string>;
|
||||||
stopGeneration: () => void;
|
stopGeneration: () => void;
|
||||||
summarize: (content: string) => Promise<Connection.TextChunk>;
|
summarize: (content: string) => Promise<string>;
|
||||||
countTokens: (prompt: string) => Promise<number>;
|
countTokens: (prompt: string) => Promise<number>;
|
||||||
}
|
}
|
||||||
export type ILLMContext = IContext & IActions;
|
export type ILLMContext = IContext & IActions;
|
||||||
|
|
@ -168,17 +168,18 @@ export const LLMContextProvider = ({ children }: { children?: any }) => {
|
||||||
isRegen,
|
isRegen,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
generate: async function* (prompt, extraSettings = {}): AsyncGenerator<Connection.TextChunk> {
|
generate: async function* (prompt, extraSettings = {}) {
|
||||||
try {
|
try {
|
||||||
console.log('[LLM.generate]', prompt);
|
console.log('[LLM.generate]', prompt);
|
||||||
|
|
||||||
|
setSpentKudos(0);
|
||||||
for await (const { text, cost } of Connection.generate(connection, prompt, {
|
for await (const { text, cost } of Connection.generate(connection, prompt, {
|
||||||
...extraSettings,
|
...extraSettings,
|
||||||
banned_tokens: bannedWords.filter(w => w.trim()),
|
banned_tokens: bannedWords.filter(w => w.trim()),
|
||||||
})) {
|
})) {
|
||||||
setSpentKudos(sk => sk + cost);
|
setSpentKudos(sk => sk + cost);
|
||||||
setTotalSpentKudos(sk => sk + cost);
|
setTotalSpentKudos(sk => sk + cost);
|
||||||
yield { text, cost };
|
yield text;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error && e.name !== 'AbortError') {
|
if (e instanceof Error && e.name !== 'AbortError') {
|
||||||
|
|
@ -203,13 +204,10 @@ export const LLMContextProvider = ({ children }: { children?: any }) => {
|
||||||
setSpentKudos(sk => sk + summary.cost);
|
setSpentKudos(sk => sk + summary.cost);
|
||||||
setTotalSpentKudos(sk => sk + summary.cost);
|
setTotalSpentKudos(sk => sk + summary.cost);
|
||||||
|
|
||||||
return {
|
return MessageTools.trimSentence(summary.text);
|
||||||
text: MessageTools.trimSentence(summary.text),
|
|
||||||
cost: summary.cost,
|
|
||||||
};
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error summarizing:', e);
|
console.error('Error summarizing:', e);
|
||||||
return { text: '', cost: 0 };
|
return '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
countTokens: async (prompt) => {
|
countTokens: async (prompt) => {
|
||||||
|
|
@ -227,7 +225,6 @@ export const LLMContextProvider = ({ children }: { children?: any }) => {
|
||||||
|
|
||||||
let messageId = messages.length - 1;
|
let messageId = messages.length - 1;
|
||||||
let text = '';
|
let text = '';
|
||||||
let cost = 0;
|
|
||||||
|
|
||||||
const { prompt, isRegen } = await actions.compilePrompt(messages, { continueLast });
|
const { prompt, isRegen } = await actions.compilePrompt(messages, { continueLast });
|
||||||
|
|
||||||
|
|
@ -239,18 +236,17 @@ export const LLMContextProvider = ({ children }: { children?: any }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
generating.setTrue();
|
generating.setTrue();
|
||||||
editSummary(messageId, 'Generating...', 0);
|
editSummary(messageId, 'Generating...');
|
||||||
for await (const chunk of actions.generate(prompt)) {
|
for await (const chunk of actions.generate(prompt)) {
|
||||||
text += chunk.text;
|
text += chunk;
|
||||||
cost += chunk.cost;
|
|
||||||
setPromptTokens(promptTokens + approximateTokens(text));
|
setPromptTokens(promptTokens + approximateTokens(text));
|
||||||
editMessage(messageId, text.trim(), cost);
|
editMessage(messageId, text.trim());
|
||||||
}
|
}
|
||||||
generating.setFalse();
|
generating.setFalse();
|
||||||
|
|
||||||
text = MessageTools.trimSentence(text);
|
text = MessageTools.trimSentence(text);
|
||||||
editMessage(messageId, text, cost);
|
editMessage(messageId, text);
|
||||||
editSummary(messageId, '', 0);
|
editSummary(messageId, '');
|
||||||
|
|
||||||
MessageTools.playReady();
|
MessageTools.playReady();
|
||||||
}
|
}
|
||||||
|
|
@ -264,8 +260,8 @@ export const LLMContextProvider = ({ children }: { children?: any }) => {
|
||||||
const message = messages[id];
|
const message = messages[id];
|
||||||
const swipe = MessageTools.getSwipe(message);
|
const swipe = MessageTools.getSwipe(message);
|
||||||
if (message.role === 'assistant' && swipe?.content?.includes('\n') && !swipe.summary) {
|
if (message.role === 'assistant' && swipe?.content?.includes('\n') && !swipe.summary) {
|
||||||
const { text, cost } = await actions.summarize(swipe.content);
|
const summary = await actions.summarize(swipe.content);
|
||||||
editSummary(id, text, cost);
|
editSummary(id, summary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,8 @@ interface IActions {
|
||||||
|
|
||||||
setMessages: (messages: IMessage[]) => void;
|
setMessages: (messages: IMessage[]) => void;
|
||||||
addMessage: (content: string, role: IMessage['role'], triggerNext?: boolean) => void;
|
addMessage: (content: string, role: IMessage['role'], triggerNext?: boolean) => void;
|
||||||
editMessage: (index: number, content: string, cost: number) => void;
|
editMessage: (index: number, content: string) => void;
|
||||||
editSummary: (index: number, summary: string, cost: number) => void;
|
editSummary: (index: number, summary: string) => void;
|
||||||
deleteMessage: (index: number) => void;
|
deleteMessage: (index: number) => void;
|
||||||
setCurrentSwipe: (index: number, swipe: number) => void;
|
setCurrentSwipe: (index: number, swipe: number) => void;
|
||||||
addSwipe: (index: number, content: string) => void;
|
addSwipe: (index: number, content: string) => void;
|
||||||
|
|
@ -270,11 +270,11 @@ export const StateContextProvider = ({ children }: { children?: any }) => {
|
||||||
]);
|
]);
|
||||||
setTriggerNext(triggerNext);
|
setTriggerNext(triggerNext);
|
||||||
},
|
},
|
||||||
editMessage: (index, content, cost) => {
|
editMessage: (index, content) => {
|
||||||
setMessages(messages => MessageTools.updateSwipe(messages, index, { content }, cost));
|
setMessages(messages => MessageTools.updateSwipe(messages, index, { content }));
|
||||||
},
|
},
|
||||||
editSummary: (index, summary, cost) => {
|
editSummary: (index, summary) => {
|
||||||
setMessages(messages => MessageTools.updateSwipe(messages, index, { summary }, cost));
|
setMessages(messages => MessageTools.updateSwipe(messages, index, { summary }));
|
||||||
},
|
},
|
||||||
deleteMessage: (index) => setMessages(messages =>
|
deleteMessage: (index) => setMessages(messages =>
|
||||||
messages.filter((_, i) => i !== index)
|
messages.filter((_, i) => i !== index)
|
||||||
|
|
@ -291,7 +291,7 @@ export const StateContextProvider = ({ children }: { children?: any }) => {
|
||||||
if (currentSwipe >= swipes.length) {
|
if (currentSwipe >= swipes.length) {
|
||||||
if (latestSwipe.content.length > 0) {
|
if (latestSwipe.content.length > 0) {
|
||||||
currentSwipe = swipes.length;
|
currentSwipe = swipes.length;
|
||||||
swipes.push({ content: '', cost: 0 });
|
swipes.push({ content: '' });
|
||||||
} else {
|
} else {
|
||||||
currentSwipe = swipes.length - 1;
|
currentSwipe = swipes.length - 1;
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +315,7 @@ export const StateContextProvider = ({ children }: { children?: any }) => {
|
||||||
messages.map(
|
messages.map(
|
||||||
(message, i) => {
|
(message, i) => {
|
||||||
if (i === index) {
|
if (i === index) {
|
||||||
const swipes = [...message.swipes, { content, cost: 0 }];
|
const swipes = [...message.swipes, { content }];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...message,
|
...message,
|
||||||
|
|
|
||||||
|
|
@ -236,17 +236,13 @@ export namespace Huggingface {
|
||||||
|
|
||||||
if (config?.chat_template?.trim()) {
|
if (config?.chat_template?.trim()) {
|
||||||
template = config.chat_template.trim()
|
template = config.chat_template.trim()
|
||||||
.replace(/raise_exception\(('[^')]+'|"[^")]+")\)/g, `''`)
|
|
||||||
.replaceAll('eos_token', `'${config.eos_token ?? ''}'`)
|
.replaceAll('eos_token', `'${config.eos_token ?? ''}'`)
|
||||||
.replaceAll('bos_token', `''`)
|
.replaceAll('bos_token', `''`);
|
||||||
.replace(/\{\{ ?(''|"") ?\}\}/g, '')
|
|
||||||
.replace(/\n'/g, `\\n'`)
|
if (config.bos_token) {
|
||||||
.replace(/\n"/g, `\\n"`)
|
template = template
|
||||||
.replace(/'\s*\+\s*'/g, '')
|
.replace(/\{\{ ?(''|"") ?\}\}/g, '');
|
||||||
.replace(/"\s*\+\s*"/g, '')
|
}
|
||||||
.replace(/\{%\s*else\s*%\}\{%\s*endif\s*%\}/gi, '{% endif %}')
|
|
||||||
.replace(/\{%\s*elif[^}]+%\}\{%\s*endif\s*%\}/gi, '{% endif %}')
|
|
||||||
.replace(/\{%\s*if[^}]+%\}\{%\s*endif\s*%\}/gi, '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,6 +308,7 @@ export namespace Huggingface {
|
||||||
try {
|
try {
|
||||||
let template = compiledTemplates.get(templateString);
|
let template = compiledTemplates.get(templateString);
|
||||||
if (!template) {
|
if (!template) {
|
||||||
|
templateString = templateString.replace(/raise_exception\(('[^')]+'|"[^")]+")\)/g, `''`)
|
||||||
template = new Template(templateString);
|
template = new Template(templateString);
|
||||||
compiledTemplates.set(templateString, template);
|
compiledTemplates.set(templateString, template);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import messageSound from '../assets/message.mp3';
|
||||||
export interface ISwipe {
|
export interface ISwipe {
|
||||||
content: string;
|
content: string;
|
||||||
summary?: string;
|
summary?: string;
|
||||||
cost: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMessage {
|
export interface IMessage {
|
||||||
|
|
@ -15,8 +14,8 @@ export interface IMessage {
|
||||||
|
|
||||||
export namespace MessageTools {
|
export namespace MessageTools {
|
||||||
export const getSwipe = (message?: IMessage | null) => message?.swipes[message?.currentSwipe];
|
export const getSwipe = (message?: IMessage | null) => message?.swipes[message?.currentSwipe];
|
||||||
export const create = (content: string, role: IMessage['role'] = 'user', technical = false, cost = 0): IMessage => (
|
export const create = (content: string, role: IMessage['role'] = 'user', technical = false): IMessage => (
|
||||||
{ role, currentSwipe: 0, swipes: [{ content, cost }], technical }
|
{ role, currentSwipe: 0, swipes: [{ content }], technical }
|
||||||
);
|
);
|
||||||
|
|
||||||
export const playReady = () => {
|
export const playReady = () => {
|
||||||
|
|
@ -98,12 +97,12 @@ export namespace MessageTools {
|
||||||
return text.trim();
|
return text.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updateSwipe = (messages: IMessage[], index: number, update: Partial<ISwipe>, cost = 0) => (
|
export const updateSwipe = (messages: IMessage[], index: number, update: Partial<ISwipe>) => (
|
||||||
messages.map(
|
messages.map(
|
||||||
(m, i) => ({
|
(m, i) => ({
|
||||||
...m,
|
...m,
|
||||||
swipes: i === index
|
swipes: i === index
|
||||||
? m.swipes.map((s, si) => (si === m.currentSwipe ? { ...s, ...update, cost: s.cost + cost } : s))
|
? m.swipes.map((s, si) => (si === m.currentSwipe ? { ...s, ...update } : s))
|
||||||
: m.swipes
|
: m.swipes
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue