You can use the following placeholders to order the context according to your needs:
@@ -3556,6 +3607,7 @@
const sessionReconnectTimer = useRef();
const useScrollSmoothing = useRef(true);
const [templates, setTemplates] = useDBTemplates(defaultPresets.instructTemplates);
+ const [templateReplacements, setTemplateReplacements] = useState(false);
const [templatesImport, setTemplatesImport] = useState(false);
const [selectedTemplate, setSelectedTemplate] = useSessionState('template', "Llama 3");
const [chatMode, setChatMode] = useSessionState('chatMode', false);
@@ -3616,13 +3668,151 @@
const [authorNoteDepth, setAuthorNoteDepth] = useSessionState('authorNoteDepth', defaultPresets.authorNoteDepth);
const [worldInfo, setWorldInfo] = useSessionState('worldInfo', defaultPresets.worldInfo);
+
+ function replacePlaceholders(string,placeholders) {
+ // give placeholders as json object
+ // { "placeholder":"replacement" }
+ return string.replace(/\{[^}]+\}/g, function (placeholder) {
+ return placeholders.hasOwnProperty(placeholder)
+ ? placeholders[placeholder]
+ : placeholder;
+ }).replace(/\\n/g, '\n')
+ };
+ useMemo(() => {
+ setTemplateReplacements({
+ "{inst}": templates[selectedTemplate]?.instPre && templates[selectedTemplate]?.instPre !== ""
+ ? templates[selectedTemplate]?.instPre
+ : "",
+ "{/inst}": templates[selectedTemplate]?.instSuf && templates[selectedTemplate]?.instSuf !== ""
+ ? templates[selectedTemplate]?.instSuf
+ : "",
+ "{sys}": templates[selectedTemplate]?.sysPre && templates[selectedTemplate]?.sysPre !== ""
+ ? templates[selectedTemplate]?.sysPre
+ : "",
+ "{/sys}": templates[selectedTemplate]?.sysSuf && templates[selectedTemplate]?.sysSuf !== ""
+ ? templates[selectedTemplate]?.sysSuf
+ : "",
+ })
+ }, [selectedTemplate,templates])
+
// AN and Memory
function handleauthorNoteTokensChange(key,value) {
setAuthorNoteTokens((prevauthorNoteTokens) => ({ ...prevauthorNoteTokens, [key]: value }));
}
+ // token counts for an
+ useEffect(() => {
+ const order = ["prefix","text","suffix"]
+ const assembled = authorNoteTokens.text && authorNoteTokens.text !== ""
+ ? order.map(key => authorNoteTokens[key]).join("")
+ : "";
+ if (assembled == "" || endpointAPI == 3) {
+ setAuthorNoteTokens((prevauthorNoteTokens) => ({ ...prevauthorNoteTokens, "tokens": 0 }))
+ return
+ }
+ const ac = new AbortController();
+ const to = setTimeout(async () => {
+ try {
+ const tokenCount = await getTokenCount({
+ endpoint,
+ endpointAPI,
+ ...(endpointAPI == 3 || endpointAPI == 0 ? { endpointAPIKey } : {}),
+ content: `${replacePlaceholders(assembled,templateReplacements)}`,
+ signal: ac.signal,
+ ...(isMikupadEndpoint ? { proxyEndpoint: sessionStorage.proxyEndpoint } : {})
+ });
+ setAuthorNoteTokens((prevauthorNoteTokens) => ({
+ ...prevauthorNoteTokens,
+ "tokens": tokenCount - 1
+ }));
+ } catch (e) {
+ if (e.name !== 'AbortError'){
+ reportError(e);
+ setAuthorNoteTokens((prevauthorNoteTokens) => ({ ...prevauthorNoteTokens, "tokens": 0 }))
+ }
+ }
+ }, 500);
+
+ ac.signal.addEventListener('abort', () => clearTimeout(to));
+ return () => ac.abort();
+ },[modalState["context"],authorNoteTokens.text,authorNoteTokens.prefix,authorNoteTokens.suffix,cancel,endpoint,endpointAPI])
+
function handleMemoryTokensChange(key,value) {
setMemoryTokens((prevMemoryTokens) => ({ ...prevMemoryTokens, [key]: value }));
}
+ // token counts for memory
+ useEffect(() => {
+ const order = ["prefix","text","suffix"]
+ const assembled = memoryTokens.text && memoryTokens.text !== ""
+ ? order.map(key => memoryTokens[key]).join("")
+ : "";
+ if (assembled == "" || endpointAPI == 3){
+ setMemoryTokens((prevMemoryTokens) => ({ ...prevMemoryTokens, "tokens": 0 }));
+ return
+ }
+
+ const ac = new AbortController();
+ const to = setTimeout(async () => {
+ try {
+ const tokenCount = await getTokenCount({
+ endpoint,
+ endpointAPI,
+ ...(endpointAPI == 3 || endpointAPI == 0 ? { endpointAPIKey } : {}),
+ content: `${replacePlaceholders(assembled,templateReplacements)}`,
+ signal: ac.signal,
+ ...(isMikupadEndpoint ? { proxyEndpoint: sessionStorage.proxyEndpoint } : {})
+ });
+ setMemoryTokens((prevMemoryTokens) => ({
+ ...prevMemoryTokens,
+ "tokens": tokenCount - 1
+ }));
+ } catch (e) {
+ if (e.name !== 'AbortError'){
+ reportError(e);
+ setMemoryTokens((prevMemoryTokens) => ({ ...prevMemoryTokens, "tokens": 0 }));
+ }
+ }
+ }, 500);
+
+ ac.signal.addEventListener('abort', () => clearTimeout(to));
+ return () => ac.abort();
+ },[modalState["context"],memoryTokens.text,memoryTokens.prefix,memoryTokens.suffix,cancel,endpoint,endpointAPI])
+ // token counts for wi
+ useEffect(() => {
+ const assembled = memoryTokens.worldInfo && memoryTokens.worldInfo !== ""
+ ? [worldInfo.prefix,memoryTokens.worldInfo,worldInfo.suffix].join("")
+ : "";
+ if (assembled == "" || endpointAPI == 3){
+ setMemoryTokens((prevMemoryTokens) => ({ ...prevMemoryTokens, "tokensWI": 0 }));
+ return
+ }
+
+ const ac = new AbortController();
+ const to = setTimeout(async () => {
+ try {
+ const tokenCount = await getTokenCount({
+ endpoint,
+ endpointAPI,
+ ...(endpointAPI == 3 || endpointAPI == 0 ? { endpointAPIKey } : {}),
+ content: `${replacePlaceholders(assembled,templateReplacements)}`,
+ signal: ac.signal,
+ ...(isMikupadEndpoint ? { proxyEndpoint: sessionStorage.proxyEndpoint } : {})
+ });
+ setMemoryTokens((prevMemoryTokens) => ({
+ ...prevMemoryTokens,
+ "tokensWI": tokenCount - 1
+ }));
+ } catch (e) {
+ if (e.name !== 'AbortError'){
+ reportError(e);
+ setMemoryTokens((prevMemoryTokens) => ({ ...prevMemoryTokens, "tokensWI": 0 }));
+ }
+ }
+ }, 500);
+
+ ac.signal.addEventListener('abort', () => clearTimeout(to));
+ return () => ac.abort();
+ },[modalState["context"],worldInfo.prefix,memoryTokens.worldInfo,worldInfo.suffix,cancel,endpoint,endpointAPI])
+
const insertTemplate = (sysInst) => {
@@ -3667,7 +3857,6 @@
onInput({ target: elem });
}
-
const toggleModal = (modalKey) => {
setModalState((prevState) => ({
...prevState,
@@ -3789,11 +3978,7 @@
// replaced, (3) instruct template placeholders are replaced (4) non-empty
// lines are joined back together.
const permContextPrompt = workingContextOrder.split("\n").map(function (line) {
- return line.replace(/\{[^}]+\}/g, function (placeholder) {
- return contextReplacements.hasOwnProperty(placeholder)
- ? contextReplacements[placeholder]
- : placeholder;
- });
+ return replacePlaceholders(line,contextReplacements)
}).filter(function (line) {
return line.trim() !== "";
}).join("\n").replace(/\\n/g, '\n');
@@ -3802,28 +3987,7 @@
}, [contextLength, promptText, memoryTokens, authorNoteTokens, authorNoteDepth, assembledWorldInfo, worldInfo.prefix, worldInfo.suffix]);
const modifiedPrompt = useMemo(() => {
- const templateReplacements = {
- "{inst}": templates[selectedTemplate]?.instPre && templates[selectedTemplate]?.instPre !== ""
- ? templates[selectedTemplate]?.instPre
- : "",
- "{/inst}": templates[selectedTemplate]?.instSuf && templates[selectedTemplate]?.instSuf !== ""
- ? templates[selectedTemplate]?.instSuf
- : "",
- "{sys}": templates[selectedTemplate]?.sysPre && templates[selectedTemplate]?.sysPre !== ""
- ? templates[selectedTemplate]?.sysPre
- : "",
- "{/sys}": templates[selectedTemplate]?.sysSuf && templates[selectedTemplate]?.sysSuf !== ""
- ? templates[selectedTemplate]?.sysSuf
- : "",
- }
- const finalPrompt = additionalContextPrompt
- .replace(/\{[^}]+\}/g, function (placeholder) {
- return templateReplacements.hasOwnProperty(placeholder)
- ? templateReplacements[placeholder]
- : placeholder;
- }).replace(/\\n/g, '\n');
-
- return finalPrompt;
+ return replacePlaceholders(additionalContextPrompt,templateReplacements);
}, [additionalContextPrompt, templates, selectedTemplate]);
async function predict(prompt = modifiedPrompt, chunkCount = promptChunks.length) {
@@ -4154,7 +4318,7 @@
}, 500);
ac.signal.addEventListener('abort', () => clearTimeout(to));
return () => ac.abort();
- }, [promptText, cancel, endpoint, endpointAPI]);
+ }, [modalState["context"], promptText, cancel, endpoint, endpointAPI]);
useEffect(() => {
if (endpointAPI != 3)
@@ -4762,7 +4926,7 @@
${CollapsibleGroup}>
<${CollapsibleGroup} label="Persistent Context">