First upload version 0.0.1
This commit is contained in:
11
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallNameGrammar.d.ts
generated
vendored
Normal file
11
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallNameGrammar.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { LlamaGrammar } from "../../LlamaGrammar.js";
|
||||
import { ChatModelFunctions } from "../../../types.js";
|
||||
import { ChatWrapper } from "../../../ChatWrapper.js";
|
||||
import { Llama } from "../../../bindings/Llama.js";
|
||||
export declare class FunctionCallNameGrammar<const Functions extends ChatModelFunctions> extends LlamaGrammar {
|
||||
private readonly _functions;
|
||||
private readonly _chatWrapper;
|
||||
constructor(llama: Llama, functions: Functions, chatWrapper: ChatWrapper);
|
||||
parseFunctionName(generatedFunctionName: string): keyof Functions & string;
|
||||
private _validateFunctions;
|
||||
}
|
||||
55
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallNameGrammar.js
generated
vendored
Normal file
55
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallNameGrammar.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { LlamaGrammar } from "../../LlamaGrammar.js";
|
||||
import { LlamaText } from "../../../utils/LlamaText.js";
|
||||
import { GbnfGrammarGenerator } from "../../../utils/gbnfJson/GbnfGrammarGenerator.js";
|
||||
import { GbnfGrammar } from "../../../utils/gbnfJson/terminals/GbnfGrammar.js";
|
||||
import { GbnfOr } from "../../../utils/gbnfJson/terminals/GbnfOr.js";
|
||||
import { GbnfVerbatimText } from "../../../utils/gbnfJson/terminals/GbnfVerbatimText.js";
|
||||
import { LlamaFunctionCallValidationError } from "./LlamaFunctionCallValidationError.js";
|
||||
export class FunctionCallNameGrammar extends LlamaGrammar {
|
||||
_functions;
|
||||
_chatWrapper;
|
||||
constructor(llama, functions, chatWrapper) {
|
||||
const grammar = getGbnfGrammarForFunctionName(functions, chatWrapper);
|
||||
super(llama, {
|
||||
grammar,
|
||||
stopGenerationTriggers: [LlamaText("\n")],
|
||||
trimWhitespaceSuffix: true
|
||||
});
|
||||
this._functions = functions;
|
||||
this._chatWrapper = chatWrapper;
|
||||
this._validateFunctions();
|
||||
}
|
||||
parseFunctionName(generatedFunctionName) {
|
||||
if (this._chatWrapper.settings.functions.call.optionalPrefixSpace && generatedFunctionName[0] === " ")
|
||||
generatedFunctionName = generatedFunctionName.slice(1);
|
||||
const newlineIndex = generatedFunctionName.indexOf("\n");
|
||||
const functionName = generatedFunctionName.slice(0, newlineIndex < 0
|
||||
? generatedFunctionName.length
|
||||
: newlineIndex);
|
||||
if (!Object.hasOwn(this._functions, functionName))
|
||||
throw new LlamaFunctionCallValidationError(`Function name "${functionName}" is not in the supplied functions object`, this._functions, this._chatWrapper, generatedFunctionName);
|
||||
return functionName;
|
||||
}
|
||||
_validateFunctions() {
|
||||
for (const functionsName of Object.keys(this._functions)) {
|
||||
if (functionsName.includes(" ") || functionsName.includes("\n") || functionsName.includes("\t"))
|
||||
throw new Error(`Function name "${functionsName}" contains spaces, new lines or tabs`);
|
||||
else if (functionsName === "")
|
||||
throw new Error("Function name cannot be an empty string");
|
||||
}
|
||||
}
|
||||
}
|
||||
function getGbnfGrammarForFunctionName(functions, chatWrapper) {
|
||||
const grammarGenerator = new GbnfGrammarGenerator();
|
||||
const functionNameGrammars = [];
|
||||
for (const functionName of Object.keys(functions))
|
||||
functionNameGrammars.push(new GbnfVerbatimText(functionName));
|
||||
const callGrammar = new GbnfOr(functionNameGrammars);
|
||||
const rootTerminal = new GbnfGrammar([
|
||||
...(chatWrapper.settings.functions.call.optionalPrefixSpace ? ["[ ]?"] : []),
|
||||
callGrammar.resolve(grammarGenerator)
|
||||
]);
|
||||
const rootGrammar = rootTerminal.getGrammar();
|
||||
return grammarGenerator.generateGbnfFile(rootGrammar + " [\\n]");
|
||||
}
|
||||
//# sourceMappingURL=FunctionCallNameGrammar.js.map
|
||||
1
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallNameGrammar.js.map
generated
vendored
Normal file
1
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallNameGrammar.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"FunctionCallNameGrammar.js","sourceRoot":"","sources":["../../../../src/evaluator/LlamaChat/utils/FunctionCallNameGrammar.ts"],"names":[],"mappings":"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"}
|
||||
16
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.d.ts
generated
vendored
Normal file
16
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import { LlamaGrammar } from "../../LlamaGrammar.js";
|
||||
import { ChatModelFunctions } from "../../../types.js";
|
||||
import { ChatWrapper } from "../../../ChatWrapper.js";
|
||||
import { Llama } from "../../../bindings/Llama.js";
|
||||
import { GbnfJsonSchema } from "../../../utils/gbnfJson/types.js";
|
||||
export declare class FunctionCallParamsGrammar<const Functions extends ChatModelFunctions> extends LlamaGrammar {
|
||||
private readonly _functions;
|
||||
private readonly _chatWrapper;
|
||||
private readonly _functionName;
|
||||
private readonly _paramsSchema;
|
||||
constructor(llama: Llama, functions: Functions, chatWrapper: ChatWrapper, functionName: string, paramsSchema: GbnfJsonSchema);
|
||||
parseParams(callText: string): {
|
||||
params: any;
|
||||
raw: string;
|
||||
};
|
||||
}
|
||||
45
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.js
generated
vendored
Normal file
45
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import { LlamaGrammar } from "../../LlamaGrammar.js";
|
||||
import { LlamaText } from "../../../utils/LlamaText.js";
|
||||
import { validateObjectAgainstGbnfSchema } from "../../../utils/gbnfJson/utils/validateObjectAgainstGbnfSchema.js";
|
||||
import { GbnfGrammarGenerator } from "../../../utils/gbnfJson/GbnfGrammarGenerator.js";
|
||||
import { getGbnfJsonTerminalForGbnfJsonSchema } from "../../../utils/gbnfJson/utils/getGbnfJsonTerminalForGbnfJsonSchema.js";
|
||||
import { LlamaFunctionCallValidationError } from "./LlamaFunctionCallValidationError.js";
|
||||
export class FunctionCallParamsGrammar extends LlamaGrammar {
|
||||
_functions;
|
||||
_chatWrapper;
|
||||
_functionName;
|
||||
_paramsSchema;
|
||||
constructor(llama, functions, chatWrapper, functionName, paramsSchema) {
|
||||
const grammar = getGbnfGrammarForFunctionParams(paramsSchema);
|
||||
super(llama, {
|
||||
grammar,
|
||||
stopGenerationTriggers: [LlamaText("\n".repeat(4))],
|
||||
trimWhitespaceSuffix: true
|
||||
});
|
||||
this._functions = functions;
|
||||
this._chatWrapper = chatWrapper;
|
||||
this._functionName = functionName;
|
||||
this._paramsSchema = paramsSchema;
|
||||
}
|
||||
parseParams(callText) {
|
||||
const endIndex = callText.lastIndexOf("\n".repeat(4));
|
||||
if (endIndex < 0)
|
||||
throw new LlamaFunctionCallValidationError(`Expected function call params for function "${this._functionName}" to end with stop generation trigger`, this._functions, this._chatWrapper, callText);
|
||||
const paramsString = callText.slice(0, endIndex);
|
||||
if (paramsString.trim().length === 0)
|
||||
throw new LlamaFunctionCallValidationError(`Expected function call params for function "${this._functionName}" to not be empty`, this._functions, this._chatWrapper, callText);
|
||||
const params = JSON.parse(paramsString);
|
||||
validateObjectAgainstGbnfSchema(params, this._paramsSchema);
|
||||
return {
|
||||
params: params, // prevent infinite TS type instantiation
|
||||
raw: paramsString
|
||||
};
|
||||
}
|
||||
}
|
||||
function getGbnfGrammarForFunctionParams(paramsSchema) {
|
||||
const grammarGenerator = new GbnfGrammarGenerator();
|
||||
const rootTerminal = getGbnfJsonTerminalForGbnfJsonSchema(paramsSchema, grammarGenerator);
|
||||
const rootGrammar = rootTerminal.resolve(grammarGenerator, true);
|
||||
return grammarGenerator.generateGbnfFile(rootGrammar + ` "${"\\n".repeat(4)}"`);
|
||||
}
|
||||
//# sourceMappingURL=FunctionCallParamsGrammar.js.map
|
||||
1
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.js.map
generated
vendored
Normal file
1
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"FunctionCallParamsGrammar.js","sourceRoot":"","sources":["../../../../src/evaluator/LlamaChat/utils/FunctionCallParamsGrammar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAC,SAAS,EAAC,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAC,+BAA+B,EAAC,MAAM,kEAAkE,CAAC;AAEjH,OAAO,EAAC,oBAAoB,EAAC,MAAM,iDAAiD,CAAC;AACrF,OAAO,EAAC,oCAAoC,EAAC,MAAM,uEAAuE,CAAC;AAI3H,OAAO,EAAC,gCAAgC,EAAC,MAAM,uCAAuC,CAAC;AAGvF,MAAM,OAAO,yBAAsE,SAAQ,YAAY;IAClF,UAAU,CAAY;IACtB,YAAY,CAAc;IAC1B,aAAa,CAAS;IACtB,aAAa,CAAiB;IAE/C,YAAmB,KAAY,EAAE,SAAoB,EAAE,WAAwB,EAAE,YAAoB,EAAE,YAA4B;QAC/H,MAAM,OAAO,GAAG,+BAA+B,CAAC,YAAY,CAAC,CAAC;QAE9D,KAAK,CAAC,KAAK,EAAE;YACT,OAAO;YACP,sBAAsB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,oBAAoB,EAAE,IAAI;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;IACtC,CAAC;IAEM,WAAW,CAAC,QAAgB;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtD,IAAI,QAAQ,GAAG,CAAC;YACZ,MAAM,IAAI,gCAAgC,CACtC,+CAA+C,IAAI,CAAC,aAAa,uCAAuC,EACxG,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,YAAY,EACjB,QAAQ,CACX,CAAC;QAEN,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEjD,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAChC,MAAM,IAAI,gCAAgC,CACtC,+CAA+C,IAAI,CAAC,aAAa,mBAAmB,EACpF,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,YAAY,EACjB,QAAQ,CACX,CAAC;QAEN,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAExC,+BAA+B,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAE5D,OAAO;YACH,MAAM,EAAE,MAAa,EAAE,yCAAyC;YAChE,GAAG,EAAE,YAAY;SACpB,CAAC;IACN,CAAC;CACJ;AAED,SAAS,+BAA+B,CAAC,YAA4B;IACjE,MAAM,gBAAgB,GAAG,IAAI,oBAAoB,EAAE,CAAC;IACpD,MAAM,YAAY,GAAG,oCAAoC,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;IAC1F,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAEjE,OAAO,gBAAgB,CAAC,gBAAgB,CAAC,WAAW,GAAG,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACpF,CAAC"}
|
||||
8
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.d.ts
generated
vendored
Normal file
8
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import { ChatModelFunctions } from "../../../types.js";
|
||||
import { ChatWrapper } from "../../../ChatWrapper.js";
|
||||
export declare class LlamaFunctionCallValidationError<const Functions extends ChatModelFunctions> extends Error {
|
||||
readonly functions: Functions;
|
||||
readonly chatWrapper: ChatWrapper;
|
||||
readonly callText: string;
|
||||
constructor(message: string, functions: Functions, chatWrapper: ChatWrapper, callText: string);
|
||||
}
|
||||
12
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.js
generated
vendored
Normal file
12
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export class LlamaFunctionCallValidationError extends Error {
|
||||
functions;
|
||||
chatWrapper;
|
||||
callText;
|
||||
constructor(message, functions, chatWrapper, callText) {
|
||||
super(message);
|
||||
this.functions = functions;
|
||||
this.chatWrapper = chatWrapper;
|
||||
this.callText = callText;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=LlamaFunctionCallValidationError.js.map
|
||||
1
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.js.map
generated
vendored
Normal file
1
node_modules/node-llama-cpp/dist/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"LlamaFunctionCallValidationError.js","sourceRoot":"","sources":["../../../../src/evaluator/LlamaChat/utils/LlamaFunctionCallValidationError.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,gCAA6E,SAAQ,KAAK;IACnF,SAAS,CAAY;IACrB,WAAW,CAAc;IACzB,QAAQ,CAAS;IAEjC,YAAmB,OAAe,EAAE,SAAoB,EAAE,WAAwB,EAAE,QAAgB;QAChG,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ"}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ChatHistoryItem, Tokenizer } from "../../../../types.js";
|
||||
import { ChatWrapper } from "../../../../ChatWrapper.js";
|
||||
export declare function eraseFirstResponseAndKeepFirstSystemChatContextShiftStrategy({ chatHistory, maxTokensCount, tokenizer, chatWrapper, lastShiftMetadata }: {
|
||||
chatHistory: ChatHistoryItem[];
|
||||
maxTokensCount: number;
|
||||
tokenizer: Tokenizer;
|
||||
chatWrapper: ChatWrapper;
|
||||
lastShiftMetadata?: object | null;
|
||||
}): Promise<{
|
||||
chatHistory: ChatHistoryItem[];
|
||||
metadata: CalculationMetadata;
|
||||
}>;
|
||||
type CalculationMetadata = {
|
||||
removedCharactersNumber: number;
|
||||
};
|
||||
export {};
|
||||
@@ -0,0 +1,254 @@
|
||||
import { isChatModelResponseFunctionCall, isChatModelResponseSegment } from "../../../../types.js";
|
||||
import { findCharacterRemovalCountToFitChatHistoryInContext } from "../../../../utils/findCharacterRemovalCountToFitChatHistoryInContext.js";
|
||||
import { truncateLlamaTextAndRoundToWords, truncateTextAndRoundToWords } from "../../../../utils/truncateTextAndRoundToWords.js";
|
||||
import { LlamaText } from "../../../../utils/LlamaText.js";
|
||||
export async function eraseFirstResponseAndKeepFirstSystemChatContextShiftStrategy({ chatHistory, maxTokensCount, tokenizer, chatWrapper, lastShiftMetadata }) {
|
||||
let initialCharactersRemovalCount = 0;
|
||||
if (isCalculationMetadata(lastShiftMetadata))
|
||||
initialCharactersRemovalCount = lastShiftMetadata.removedCharactersNumber;
|
||||
const { removedCharactersCount, compressedChatHistory } = await findCharacterRemovalCountToFitChatHistoryInContext({
|
||||
chatHistory,
|
||||
tokensCountToFit: maxTokensCount,
|
||||
initialCharactersRemovalCount,
|
||||
tokenizer,
|
||||
chatWrapper,
|
||||
failedCompressionErrorMessage: "Failed to compress chat history for context shift due to a too long prompt or system message that cannot be compressed without affecting the generation quality. " +
|
||||
"Consider increasing the context size or shortening the long prompt or system message.",
|
||||
compressChatHistory({ chatHistory, charactersToRemove, estimatedCharactersPerToken }) {
|
||||
const res = chatHistory.map((item) => structuredClone(item));
|
||||
let charactersLeftToRemove = charactersToRemove;
|
||||
function compressFunctionCalls() {
|
||||
for (let i = res.length - 1; i >= 0 && charactersLeftToRemove > 0; i--) {
|
||||
const historyItem = res[i];
|
||||
if (historyItem.type !== "model")
|
||||
continue;
|
||||
for (let t = historyItem.response.length - 1; t >= 0 && charactersLeftToRemove > 0; t--) {
|
||||
const item = historyItem.response[t];
|
||||
if (typeof item === "string" || item.type !== "functionCall")
|
||||
continue;
|
||||
if (item.rawCall == null)
|
||||
continue;
|
||||
const originalRawCallTokensLength = LlamaText.fromJSON(item.rawCall).tokenize(tokenizer, "trimLeadingSpace").length;
|
||||
const newRawCallText = chatWrapper.generateFunctionCall(item.name, item.params);
|
||||
const newRawCallTextTokensLength = newRawCallText.tokenize(tokenizer, "trimLeadingSpace").length;
|
||||
if (newRawCallTextTokensLength < originalRawCallTokensLength) {
|
||||
item.rawCall = newRawCallText.toJSON();
|
||||
charactersLeftToRemove -= ((originalRawCallTokensLength - newRawCallTextTokensLength) * estimatedCharactersPerToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function removeHistoryThatLedToModelResponseAtIndex(index) {
|
||||
let removedItems = 0;
|
||||
for (let i = index - 1; i >= 0; i--) {
|
||||
const historyItem = res[i];
|
||||
if (historyItem == null)
|
||||
continue;
|
||||
if (historyItem.type === "model")
|
||||
break; // stop removing history items if we reach another model response
|
||||
if (i === 0 && historyItem.type === "system")
|
||||
break; // keep the first system message
|
||||
if (historyItem.type === "user" || historyItem.type === "system") {
|
||||
const newText = truncateLlamaTextAndRoundToWords(LlamaText.fromJSON(historyItem.text), charactersLeftToRemove, undefined, false);
|
||||
const newTextString = newText.toString();
|
||||
const historyItemString = LlamaText.fromJSON(historyItem.text).toString();
|
||||
if (newText.values.length === 0) {
|
||||
res.splice(i, 1);
|
||||
i++;
|
||||
removedItems++;
|
||||
charactersLeftToRemove -= historyItemString.length;
|
||||
}
|
||||
else if (newTextString.length < historyItemString.length) {
|
||||
charactersLeftToRemove -= historyItemString.length - newTextString.length;
|
||||
if (historyItem.type === "user")
|
||||
historyItem.text = newText.toString();
|
||||
else
|
||||
historyItem.text = newText.toJSON();
|
||||
}
|
||||
}
|
||||
else {
|
||||
void historyItem;
|
||||
}
|
||||
}
|
||||
return removedItems;
|
||||
}
|
||||
function compressHistoryThatLedToModelResponseAtIndex(index, keepTokensCount = 0) {
|
||||
let removedItems = 0;
|
||||
let promptStartIndex = undefined;
|
||||
for (let i = index - 1; i >= 0; i--) {
|
||||
const historyItem = res[i];
|
||||
if (historyItem == null)
|
||||
continue;
|
||||
if (historyItem.type === "model") {
|
||||
promptStartIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
if (i === 0 && historyItem.type === "system") {
|
||||
promptStartIndex = i + 1;
|
||||
break; // keep the first system message
|
||||
}
|
||||
}
|
||||
if (promptStartIndex == null || promptStartIndex >= index)
|
||||
return 0;
|
||||
for (let i = promptStartIndex; i < index && charactersLeftToRemove > 0; i++) {
|
||||
const historyItem = res[i];
|
||||
if (historyItem == null || historyItem.type !== "user")
|
||||
continue;
|
||||
let removeChars = Math.min(charactersLeftToRemove, historyItem.text.length);
|
||||
if (keepTokensCount > 0) {
|
||||
removeChars -= Math.floor(keepTokensCount * estimatedCharactersPerToken);
|
||||
if (removeChars < 0)
|
||||
removeChars = 0;
|
||||
keepTokensCount -= Math.min(keepTokensCount, Math.max(0, historyItem.text.length - removeChars) / estimatedCharactersPerToken);
|
||||
}
|
||||
const newText = truncateTextAndRoundToWords(historyItem.text, removeChars, undefined, false);
|
||||
if (newText.length === 0) {
|
||||
res.splice(i, 1);
|
||||
i--;
|
||||
index--;
|
||||
removedItems++;
|
||||
charactersLeftToRemove -= historyItem.text.length;
|
||||
}
|
||||
else {
|
||||
charactersLeftToRemove -= historyItem.text.length - newText.length;
|
||||
historyItem.text = newText;
|
||||
}
|
||||
}
|
||||
return removedItems;
|
||||
}
|
||||
function removeEmptySegmentsFromModelResponse(modelResponse) {
|
||||
const stack = [];
|
||||
for (let t = 0; t < modelResponse.length && charactersLeftToRemove > 0; t++) {
|
||||
const item = modelResponse[t];
|
||||
const isLastItem = t === modelResponse.length - 1;
|
||||
if (!isChatModelResponseSegment(item))
|
||||
continue;
|
||||
const type = item.segmentType;
|
||||
const topStack = stack.at(-1);
|
||||
if (topStack?.type === type) {
|
||||
if (item.ended && item.text === "" && topStack.canRemove) {
|
||||
modelResponse.splice(t, 1);
|
||||
t--;
|
||||
modelResponse.splice(topStack.startIndex, 1);
|
||||
t--;
|
||||
stack.pop();
|
||||
}
|
||||
else if (!item.ended && item.text === "" && !isLastItem) {
|
||||
modelResponse.splice(t, 1);
|
||||
t--;
|
||||
}
|
||||
else if (!item.ended && item.text !== "")
|
||||
topStack.canRemove = false;
|
||||
else if (item.ended)
|
||||
stack.pop();
|
||||
}
|
||||
else if (!item.ended)
|
||||
stack.push({
|
||||
type,
|
||||
startIndex: t,
|
||||
canRemove: item.text === ""
|
||||
});
|
||||
}
|
||||
}
|
||||
function compressFirstModelResponse() {
|
||||
for (let i = 0; i < res.length && charactersLeftToRemove > 0; i++) {
|
||||
const historyItem = res[i];
|
||||
const isLastHistoryItem = i === res.length - 1;
|
||||
if (historyItem.type !== "model")
|
||||
continue;
|
||||
for (let t = 0; t < historyItem.response.length && charactersLeftToRemove > 0; t++) {
|
||||
const item = historyItem.response[t];
|
||||
const isLastText = t === historyItem.response.length - 1;
|
||||
if (isLastHistoryItem && isLastText)
|
||||
continue;
|
||||
if (typeof item === "string") {
|
||||
const newText = truncateTextAndRoundToWords(item, charactersLeftToRemove, undefined, true);
|
||||
if (newText === "") {
|
||||
historyItem.response.splice(t, 1);
|
||||
t--;
|
||||
charactersLeftToRemove -= item.length;
|
||||
}
|
||||
else if (newText.length < item.length) {
|
||||
historyItem.response[t] = newText;
|
||||
charactersLeftToRemove -= item.length - newText.length;
|
||||
}
|
||||
}
|
||||
else if (isChatModelResponseFunctionCall(item)) {
|
||||
historyItem.response.splice(t, 1);
|
||||
t--;
|
||||
const functionCallAndResultTokenUsage = chatWrapper.generateFunctionCallsAndResults([item], true)
|
||||
.tokenize(tokenizer, "trimLeadingSpace").length;
|
||||
charactersLeftToRemove -= functionCallAndResultTokenUsage * estimatedCharactersPerToken;
|
||||
}
|
||||
else if (isChatModelResponseSegment(item)) {
|
||||
if (item.text !== "") {
|
||||
const newText = truncateTextAndRoundToWords(item.text, charactersLeftToRemove, undefined, true);
|
||||
if (newText === "" && item.ended) {
|
||||
const emptySegmentTokenUsage = chatWrapper.generateModelResponseText([{ ...item, text: "" }], true)
|
||||
.tokenize(tokenizer, "trimLeadingSpace").length;
|
||||
historyItem.response.splice(t, 1);
|
||||
t--;
|
||||
charactersLeftToRemove -= item.text.length + emptySegmentTokenUsage * estimatedCharactersPerToken;
|
||||
}
|
||||
else {
|
||||
charactersLeftToRemove -= item.text.length - newText.length;
|
||||
item.text = newText;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
void item;
|
||||
}
|
||||
removeEmptySegmentsFromModelResponse(historyItem.response);
|
||||
if (historyItem.response.length === 0) {
|
||||
// if the model response is removed from the history,
|
||||
// the things that led to it are not important anymore
|
||||
i -= removeHistoryThatLedToModelResponseAtIndex(i);
|
||||
res.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
function compressLastModelResponse(minCharactersToKeep = 60) {
|
||||
const lastHistoryItem = res[res.length - 1];
|
||||
if (lastHistoryItem == null || lastHistoryItem.type !== "model")
|
||||
return;
|
||||
const lastResponseItem = lastHistoryItem.response[lastHistoryItem.response.length - 1];
|
||||
if (lastResponseItem == null || typeof lastResponseItem !== "string")
|
||||
return;
|
||||
compressHistoryThatLedToModelResponseAtIndex(res.length - 1, maxTokensCount / 4);
|
||||
if (charactersLeftToRemove <= 0)
|
||||
return;
|
||||
const nextTextLength = Math.max(Math.min(lastResponseItem.length, minCharactersToKeep), lastResponseItem.length - charactersLeftToRemove);
|
||||
const charactersToRemoveFromText = lastResponseItem.length - nextTextLength;
|
||||
const newText = truncateTextAndRoundToWords(lastResponseItem, charactersToRemoveFromText, undefined, true);
|
||||
if (newText.length < lastResponseItem.length) {
|
||||
lastHistoryItem.response[lastHistoryItem.response.length - 1] = newText;
|
||||
charactersLeftToRemove -= lastResponseItem.length - newText.length;
|
||||
}
|
||||
if (charactersLeftToRemove <= 0)
|
||||
return;
|
||||
compressHistoryThatLedToModelResponseAtIndex(res.length - 1);
|
||||
}
|
||||
compressFunctionCalls();
|
||||
if (charactersLeftToRemove <= 0)
|
||||
return res;
|
||||
compressFirstModelResponse();
|
||||
if (charactersLeftToRemove <= 0)
|
||||
return res;
|
||||
compressLastModelResponse();
|
||||
return res;
|
||||
}
|
||||
});
|
||||
const newMetadata = {
|
||||
removedCharactersNumber: removedCharactersCount
|
||||
};
|
||||
return {
|
||||
chatHistory: compressedChatHistory,
|
||||
metadata: newMetadata
|
||||
};
|
||||
}
|
||||
function isCalculationMetadata(metadata) {
|
||||
return metadata != null && typeof metadata === "object" && typeof metadata.removedCharactersNumber === "number";
|
||||
}
|
||||
//# sourceMappingURL=eraseFirstResponseAndKeepFirstSystemChatContextShiftStrategy.js.map
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user