diff --git a/package-lock.json b/package-lock.json index e3d0eade1..42b187bcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "ip-matching": "^2.1.2", "ipaddr.js": "^2.0.1", "jimp": "^0.22.10", + "js-sha256": "^0.11.0", "localforage": "^1.10.0", "lodash": "^4.17.21", "mime-types": "^2.1.35", @@ -4882,6 +4883,12 @@ "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", "license": "BSD-3-Clause" }, + "node_modules/js-sha256": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==", + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", diff --git a/package.json b/package.json index 3608d9775..5a2c4f15c 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "ip-matching": "^2.1.2", "ipaddr.js": "^2.0.1", "jimp": "^0.22.10", + "js-sha256": "^0.11.0", "localforage": "^1.10.0", "lodash": "^4.17.21", "mime-types": "^2.1.35", diff --git a/public/script.js b/public/script.js index f7c88cc6a..a3446d258 100644 --- a/public/script.js +++ b/public/script.js @@ -1250,9 +1250,9 @@ async function getStatusTextgen() { const data = await response.json(); if (data) { - const chat_template = data.chat_template; + const { chat_template, chat_template_hash } = data; console.log(`We have chat template ${chat_template.split('\n')[0]}...`); - const templates = await deriveTemplatesFromChatTemplate(chat_template); + const templates = await deriveTemplatesFromChatTemplate(chat_template, chat_template_hash); if (templates) { const { context, instruct } = templates; selectContextPreset(context, { isAuto: true }); diff --git a/public/scripts/chat-cemplates.js b/public/scripts/chat-cemplates.js index f70f9fc18..2dfaebbb6 100644 --- a/public/scripts/chat-cemplates.js +++ b/public/scripts/chat-cemplates.js @@ -1,14 +1,3 @@ -// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest -async function digestMessage(message) { - const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array - const hashBuffer = await window.crypto.subtle.digest('SHA-256', msgUint8); // hash the message - const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array - const hashHex = hashArray - .map((b) => b.toString(16).padStart(2, '0')) - .join(''); // convert bytes to hex string - return hashHex; -} - // the hash can be obtained from command line e.g. via: MODEL=path_to_model; python -c "import json, hashlib, sys; print(hashlib.sha256(json.load(open('"$MODEL"/tokenizer_config.json'))['chat_template'].strip().encode()).hexdigest())" // note that chat templates must be trimmed to match the llama.cpp metadata value const derivations = { @@ -66,8 +55,7 @@ const derivations = { }, }; -export async function deriveTemplatesFromChatTemplate(chat_template) { - const hash = await digestMessage(chat_template); +export async function deriveTemplatesFromChatTemplate(chat_template, hash) { if (hash in derivations) { return derivations[hash]; } diff --git a/src/endpoints/backends/text-completions.js b/src/endpoints/backends/text-completions.js index 1c5bdb75a..fec67481f 100644 --- a/src/endpoints/backends/text-completions.js +++ b/src/endpoints/backends/text-completions.js @@ -16,6 +16,7 @@ import { } from '../../constants.js'; import { forwardFetchResponse, trimV1, getConfigValue } from '../../util.js'; import { setAdditionalHeaders } from '../../additional-headers.js'; +import { sha256 } from 'js-sha256'; export const router = express.Router(); @@ -260,6 +261,7 @@ router.post('/chat_template', jsonParser, async function (request, response) { /** @type {any} */ const chatTemplate = await chatTemplateReply.json(); + chatTemplate['chat_template_hash'] = sha256.create().update(chatTemplate['chat_template']).hex(); return response.send(chatTemplate); } catch (error) { console.error(error);