node-llama-cpp 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/ChatWrapper.d.ts +3 -5
- package/dist/ChatWrapper.js +57 -5
- package/dist/ChatWrapper.js.map +1 -1
- package/dist/bindings/AddonTypes.d.ts +1 -1
- package/dist/bindings/Llama.js +2 -0
- package/dist/bindings/Llama.js.map +1 -1
- package/dist/bindings/utils/compileLLamaCpp.js +2 -0
- package/dist/bindings/utils/compileLLamaCpp.js.map +1 -1
- package/dist/chatWrappers/AlpacaChatWrapper.js.map +1 -1
- package/dist/chatWrappers/DeepSeekChatWrapper.d.ts +37 -0
- package/dist/chatWrappers/DeepSeekChatWrapper.js +294 -0
- package/dist/chatWrappers/DeepSeekChatWrapper.js.map +1 -0
- package/dist/chatWrappers/FalconChatWrapper.js.map +1 -1
- package/dist/chatWrappers/FunctionaryChatWrapper.js +40 -14
- package/dist/chatWrappers/FunctionaryChatWrapper.js.map +1 -1
- package/dist/chatWrappers/GeneralChatWrapper.js.map +1 -1
- package/dist/chatWrappers/Llama2ChatWrapper.js.map +1 -1
- package/dist/chatWrappers/Llama3_1ChatWrapper.d.ts +0 -3
- package/dist/chatWrappers/Llama3_1ChatWrapper.js +24 -13
- package/dist/chatWrappers/Llama3_1ChatWrapper.js.map +1 -1
- package/dist/chatWrappers/Llama3_2LightweightChatWrapper.js +22 -11
- package/dist/chatWrappers/Llama3_2LightweightChatWrapper.js.map +1 -1
- package/dist/chatWrappers/MistralChatWrapper.d.ts +2 -1
- package/dist/chatWrappers/MistralChatWrapper.js +39 -28
- package/dist/chatWrappers/MistralChatWrapper.js.map +1 -1
- package/dist/chatWrappers/QwenChatWrapper.d.ts +21 -0
- package/dist/chatWrappers/QwenChatWrapper.js +162 -0
- package/dist/chatWrappers/QwenChatWrapper.js.map +1 -0
- package/dist/chatWrappers/generic/JinjaTemplateChatWrapper.d.ts +41 -3
- package/dist/chatWrappers/generic/JinjaTemplateChatWrapper.js +343 -126
- package/dist/chatWrappers/generic/JinjaTemplateChatWrapper.js.map +1 -1
- package/dist/chatWrappers/generic/TemplateChatWrapper.d.ts +17 -1
- package/dist/chatWrappers/generic/TemplateChatWrapper.js +10 -2
- package/dist/chatWrappers/generic/TemplateChatWrapper.js.map +1 -1
- package/dist/chatWrappers/generic/utils/UniqueIdGenerator.d.ts +7 -0
- package/dist/chatWrappers/generic/utils/UniqueIdGenerator.js +30 -0
- package/dist/chatWrappers/generic/utils/UniqueIdGenerator.js.map +1 -0
- package/dist/chatWrappers/generic/utils/chatHistoryFunctionCallMessageTemplate.d.ts +5 -4
- package/dist/chatWrappers/generic/utils/extractFunctionCallSettingsFromJinjaTemplate.d.ts +19 -0
- package/dist/chatWrappers/generic/utils/extractFunctionCallSettingsFromJinjaTemplate.js +446 -0
- package/dist/chatWrappers/generic/utils/extractFunctionCallSettingsFromJinjaTemplate.js.map +1 -0
- package/dist/chatWrappers/generic/utils/extractSegmentSettingsFromTokenizerAndChatTemplate.d.ts +2 -0
- package/dist/chatWrappers/generic/utils/extractSegmentSettingsFromTokenizerAndChatTemplate.js +38 -0
- package/dist/chatWrappers/generic/utils/extractSegmentSettingsFromTokenizerAndChatTemplate.js.map +1 -0
- package/dist/chatWrappers/generic/utils/getFirstValidResult.d.ts +6 -0
- package/dist/chatWrappers/generic/utils/getFirstValidResult.js +19 -0
- package/dist/chatWrappers/generic/utils/getFirstValidResult.js.map +1 -0
- package/dist/chatWrappers/generic/utils/squashChatHistoryItems.d.ts +2 -0
- package/dist/chatWrappers/generic/utils/squashChatHistoryItems.js +35 -0
- package/dist/chatWrappers/generic/utils/squashChatHistoryItems.js.map +1 -0
- package/dist/chatWrappers/generic/utils/templateSegmentOptionsToChatWrapperSettings.d.ts +22 -0
- package/dist/chatWrappers/generic/utils/templateSegmentOptionsToChatWrapperSettings.js +28 -0
- package/dist/chatWrappers/generic/utils/templateSegmentOptionsToChatWrapperSettings.js.map +1 -0
- package/dist/chatWrappers/utils/ChatModelFunctionsDocumentationGenerator.d.ts +3 -0
- package/dist/chatWrappers/utils/ChatModelFunctionsDocumentationGenerator.js +25 -0
- package/dist/chatWrappers/utils/ChatModelFunctionsDocumentationGenerator.js.map +1 -1
- package/dist/chatWrappers/utils/isJinjaTemplateEquivalentToSpecializedChatWrapper.js +197 -30
- package/dist/chatWrappers/utils/isJinjaTemplateEquivalentToSpecializedChatWrapper.js.map +1 -1
- package/dist/chatWrappers/utils/resolveChatWrapper.d.ts +48 -3
- package/dist/chatWrappers/utils/resolveChatWrapper.js +15 -5
- package/dist/chatWrappers/utils/resolveChatWrapper.js.map +1 -1
- package/dist/cli/commands/ChatCommand.js +38 -7
- package/dist/cli/commands/ChatCommand.js.map +1 -1
- package/dist/cli/recommendedModels.js +93 -10
- package/dist/cli/recommendedModels.js.map +1 -1
- package/dist/cli/utils/resolveModelRecommendationFileOptions.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/evaluator/LlamaChat/LlamaChat.d.ts +87 -5
- package/dist/evaluator/LlamaChat/LlamaChat.js +781 -196
- package/dist/evaluator/LlamaChat/LlamaChat.js.map +1 -1
- package/dist/evaluator/LlamaChat/utils/contextShiftStrategies/eraseFirstResponseAndKeepFirstSystemChatContextShiftStrategy.js +55 -1
- package/dist/evaluator/LlamaChat/utils/contextShiftStrategies/eraseFirstResponseAndKeepFirstSystemChatContextShiftStrategy.js.map +1 -1
- package/dist/evaluator/LlamaChatSession/LlamaChatSession.d.ts +22 -7
- package/dist/evaluator/LlamaChatSession/LlamaChatSession.js +28 -8
- package/dist/evaluator/LlamaChatSession/LlamaChatSession.js.map +1 -1
- package/dist/evaluator/LlamaChatSession/utils/LlamaChatSessionPromptCompletionEngine.js +1 -1
- package/dist/evaluator/LlamaChatSession/utils/LlamaChatSessionPromptCompletionEngine.js.map +1 -1
- package/dist/evaluator/LlamaChatSession/utils/defineChatSessionFunction.d.ts +1 -1
- package/dist/evaluator/LlamaChatSession/utils/defineChatSessionFunction.js.map +1 -1
- package/dist/evaluator/LlamaCompletion.js +61 -48
- package/dist/evaluator/LlamaCompletion.js.map +1 -1
- package/dist/evaluator/LlamaGrammar.d.ts +2 -2
- package/dist/evaluator/LlamaGrammar.js +5 -3
- package/dist/evaluator/LlamaGrammar.js.map +1 -1
- package/dist/evaluator/LlamaModel/LlamaModel.d.ts +3 -1
- package/dist/evaluator/LlamaModel/LlamaModel.js +4 -1
- package/dist/evaluator/LlamaModel/LlamaModel.js.map +1 -1
- package/dist/evaluator/LlamaRankingContext.js +1 -1
- package/dist/evaluator/LlamaRankingContext.js.map +1 -1
- package/dist/gguf/types/GgufMetadataTypes.d.ts +1 -1
- package/dist/gguf/types/GgufMetadataTypes.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +40 -2
- package/dist/types.js +7 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/LlamaText.js +8 -9
- package/dist/utils/LlamaText.js.map +1 -1
- package/dist/utils/OpenAIFormat.d.ts +177 -0
- package/dist/utils/OpenAIFormat.js +488 -0
- package/dist/utils/OpenAIFormat.js.map +1 -0
- package/dist/utils/TokenStreamRegulator.d.ts +2 -0
- package/dist/utils/TokenStreamRegulator.js +12 -0
- package/dist/utils/TokenStreamRegulator.js.map +1 -1
- package/dist/utils/getChatWrapperSegmentDefinition.d.ts +2 -0
- package/dist/utils/getChatWrapperSegmentDefinition.js +7 -0
- package/dist/utils/getChatWrapperSegmentDefinition.js.map +1 -0
- package/dist/utils/optionsMatrix.d.ts +58 -0
- package/dist/utils/optionsMatrix.js +97 -0
- package/dist/utils/optionsMatrix.js.map +1 -0
- package/dist/utils/parseModelUri.js +1 -1
- package/dist/utils/parseModelUri.js.map +1 -1
- package/dist/utils/resolveModelFile.js +2 -0
- package/dist/utils/resolveModelFile.js.map +1 -1
- package/llama/addon/AddonContext.cpp +11 -9
- package/llama/binariesGithubRelease.json +1 -1
- package/llama/gitRelease.bundle +0 -0
- package/llama/grammars/README.md +4 -4
- package/llama/llama.cpp.info.json +2 -2
- package/package.json +48 -45
- package/templates/packed/electron-typescript-react.json +1 -1
- package/templates/packed/node-typescript.json +1 -1
|
@@ -2,7 +2,16 @@ import { Template } from "@huggingface/jinja";
|
|
|
2
2
|
import { splitText } from "lifecycle-utils";
|
|
3
3
|
import { SpecialToken, LlamaText, SpecialTokensText } from "../../utils/LlamaText.js";
|
|
4
4
|
import { ChatWrapper } from "../../ChatWrapper.js";
|
|
5
|
+
import { fromChatHistoryToIntermediateOpenAiMessages, fromIntermediateToCompleteOpenAiMessages } from "../../utils/OpenAIFormat.js";
|
|
6
|
+
import { removeUndefinedFields } from "../../utils/removeNullFields.js";
|
|
7
|
+
import { jsonDumps } from "../utils/jsonDumps.js";
|
|
8
|
+
import { tryMatrix } from "../../utils/optionsMatrix.js";
|
|
5
9
|
import { parseFunctionCallMessageTemplate } from "./utils/chatHistoryFunctionCallMessageTemplate.js";
|
|
10
|
+
import { templateSegmentOptionsToChatWrapperSettings } from "./utils/templateSegmentOptionsToChatWrapperSettings.js";
|
|
11
|
+
import { UniqueIdGenerator } from "./utils/UniqueIdGenerator.js";
|
|
12
|
+
import { extractFunctionCallSettingsFromJinjaTemplate } from "./utils/extractFunctionCallSettingsFromJinjaTemplate.js";
|
|
13
|
+
import { squashChatHistoryItems } from "./utils/squashChatHistoryItems.js";
|
|
14
|
+
import { extractSegmentSettingsFromTokenizerAndChatTemplate } from "./utils/extractSegmentSettingsFromTokenizerAndChatTemplate.js";
|
|
6
15
|
const defaultConvertUnsupportedSystemMessagesToUserMessagesFormat = {
|
|
7
16
|
format: "### System message\n\n{{message}}\n\n----"
|
|
8
17
|
};
|
|
@@ -25,6 +34,10 @@ const defaultConvertUnsupportedSystemMessagesToUserMessagesFormat = {
|
|
|
25
34
|
* // functionCallMessageTemplate: { // optional
|
|
26
35
|
* // call: "[[call: {{functionName}}({{functionParams}})]]",
|
|
27
36
|
* // result: " [[result: {{functionCallResult}}]]"
|
|
37
|
+
* // },
|
|
38
|
+
* // segments: {
|
|
39
|
+
* // thoughtTemplate: "<think>{{content}}</think>",
|
|
40
|
+
* // reopenThoughtAfterFunctionCalls: true
|
|
28
41
|
* // }
|
|
29
42
|
* });
|
|
30
43
|
* ```
|
|
@@ -43,11 +56,17 @@ export class JinjaTemplateChatWrapper extends ChatWrapper {
|
|
|
43
56
|
trimLeadingWhitespaceInResponses;
|
|
44
57
|
additionalRenderParameters;
|
|
45
58
|
/** @internal */ _jinjaTemplate;
|
|
59
|
+
/** @internal */ _usingJinjaFunctionCallTemplate = false;
|
|
60
|
+
/** @internal */ _stringifyFunctionParams = false;
|
|
61
|
+
/** @internal */ _stringifyFunctionResult = false;
|
|
62
|
+
/** @internal */ _combineJinjaModelMessageAndToolCalls = true;
|
|
63
|
+
/** @internal */ _endJinjaMessagesWithUserMessage = false;
|
|
46
64
|
/**
|
|
47
65
|
* @param options
|
|
48
66
|
*/
|
|
49
|
-
constructor(
|
|
67
|
+
constructor(options) {
|
|
50
68
|
super();
|
|
69
|
+
const { template, modelRoleName = "assistant", userRoleName = "user", systemRoleName = "system", convertUnsupportedSystemMessagesToUserMessages = defaultConvertUnsupportedSystemMessagesToUserMessagesFormat, functionCallMessageTemplate = "auto", joinAdjacentMessagesOfTheSameType = true, trimLeadingWhitespaceInResponses = true, additionalRenderParameters, segments, tokenizer, _requireFunctionCallSettingsExtraction = false } = options;
|
|
51
70
|
if (template == null)
|
|
52
71
|
throw new Error("template cannot be null");
|
|
53
72
|
this.template = template;
|
|
@@ -59,50 +78,219 @@ export class JinjaTemplateChatWrapper extends ChatWrapper {
|
|
|
59
78
|
this.joinAdjacentMessagesOfTheSameType = joinAdjacentMessagesOfTheSameType;
|
|
60
79
|
this.trimLeadingWhitespaceInResponses = trimLeadingWhitespaceInResponses;
|
|
61
80
|
this.additionalRenderParameters = additionalRenderParameters;
|
|
62
|
-
this.settings = {
|
|
63
|
-
...ChatWrapper.defaultSettings,
|
|
64
|
-
functions: parseFunctionCallMessageTemplate(functionCallMessageTemplate) ?? ChatWrapper.defaultSettings.functions
|
|
65
|
-
};
|
|
66
81
|
if (this.convertUnsupportedSystemMessagesToUserMessages != null && !this.convertUnsupportedSystemMessagesToUserMessages.format.includes("{{message}}"))
|
|
67
82
|
throw new Error('convertUnsupportedSystemMessagesToUserMessages format must include "{{message}}"');
|
|
68
83
|
this._jinjaTemplate = new Template(this.template);
|
|
69
|
-
|
|
84
|
+
this.settings = {
|
|
85
|
+
...ChatWrapper.defaultSettings,
|
|
86
|
+
segments: templateSegmentOptionsToChatWrapperSettings(segments)
|
|
87
|
+
};
|
|
88
|
+
const { supportsSystemMessages, needsToEndJinjaMessagesWithUserMessage } = this._runSanityTest();
|
|
70
89
|
this.settings = {
|
|
71
90
|
...this.settings,
|
|
72
|
-
supportsSystemMessages
|
|
91
|
+
supportsSystemMessages,
|
|
92
|
+
segments: {
|
|
93
|
+
...this.settings.segments,
|
|
94
|
+
...extractSegmentSettingsFromTokenizerAndChatTemplate(this.template, tokenizer)
|
|
95
|
+
}
|
|
73
96
|
};
|
|
97
|
+
if (needsToEndJinjaMessagesWithUserMessage)
|
|
98
|
+
this._endJinjaMessagesWithUserMessage = true;
|
|
99
|
+
let functionCallSettings = parseFunctionCallMessageTemplate((functionCallMessageTemplate === "auto" || functionCallMessageTemplate === "noJinja")
|
|
100
|
+
? undefined
|
|
101
|
+
: functionCallMessageTemplate);
|
|
102
|
+
if (functionCallSettings == null && functionCallMessageTemplate !== "noJinja") {
|
|
103
|
+
try {
|
|
104
|
+
const idsGenerator = new UniqueIdGenerator(this.template + this.modelRoleName + this.userRoleName + this.systemRoleName +
|
|
105
|
+
(this.convertUnsupportedSystemMessagesToUserMessages?.format ?? ""));
|
|
106
|
+
const extractedSettings = extractFunctionCallSettingsFromJinjaTemplate({
|
|
107
|
+
idsGenerator,
|
|
108
|
+
renderTemplate: ({ chatHistory, functions, additionalParams, stringifyFunctionParams, stringifyFunctionResults, combineModelMessageAndToolCalls, squashModelTextResponses = true }) => {
|
|
109
|
+
const render = (convertSystemMessagesToUserMessagesFormat, wipeFunctionCallIds) => {
|
|
110
|
+
const { messages: intermediateMessages, tools } = fromChatHistoryToIntermediateOpenAiMessages({
|
|
111
|
+
chatHistory: this._transformChatHistory(chatHistory, {
|
|
112
|
+
convertSystemMessagesToUserMessagesFormat,
|
|
113
|
+
joinAdjacentMessagesOfTheSameType: !squashModelTextResponses
|
|
114
|
+
? false
|
|
115
|
+
: undefined
|
|
116
|
+
}).transformedHistory,
|
|
117
|
+
chatWrapperSettings: this.settings,
|
|
118
|
+
useRawValues: false,
|
|
119
|
+
functions,
|
|
120
|
+
stringifyFunctionParams,
|
|
121
|
+
stringifyFunctionResults,
|
|
122
|
+
combineModelMessageAndToolCalls,
|
|
123
|
+
squashModelTextResponses
|
|
124
|
+
});
|
|
125
|
+
const messages = fromIntermediateToCompleteOpenAiMessages(intermediateMessages)
|
|
126
|
+
.map((item) => {
|
|
127
|
+
if (!wipeFunctionCallIds)
|
|
128
|
+
return item;
|
|
129
|
+
if (item.role === "assistant" && item["tool_calls"] != null && item["tool_calls"].length > 0) {
|
|
130
|
+
for (const toolCall of item["tool_calls"]) {
|
|
131
|
+
if (wipeFunctionCallIds === "align")
|
|
132
|
+
toolCall.id = "fc_1_0001";
|
|
133
|
+
else
|
|
134
|
+
delete toolCall.id;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else if (item.role === "tool") {
|
|
138
|
+
if (wipeFunctionCallIds === "align")
|
|
139
|
+
item["tool_call_id"] = "fc_1_0001";
|
|
140
|
+
else
|
|
141
|
+
delete item["tool_call_id"];
|
|
142
|
+
}
|
|
143
|
+
return item;
|
|
144
|
+
});
|
|
145
|
+
const lastJinjaItem = messages.at(-1);
|
|
146
|
+
let eraseRenderedJinjaFromId;
|
|
147
|
+
if (this._endJinjaMessagesWithUserMessage && lastJinjaItem?.role === this.modelRoleName &&
|
|
148
|
+
typeof lastJinjaItem.content === "string" &&
|
|
149
|
+
lastJinjaItem.content.length > 0 &&
|
|
150
|
+
(lastJinjaItem["tool_calls"] == null ||
|
|
151
|
+
lastJinjaItem["tool_calls"]?.length === 0)) {
|
|
152
|
+
eraseRenderedJinjaFromId = lastJinjaItem.content;
|
|
153
|
+
messages.push({
|
|
154
|
+
role: this.userRoleName,
|
|
155
|
+
content: idsGenerator.generateId()
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
let res = this._jinjaTemplate.render({
|
|
159
|
+
...(this.additionalRenderParameters == null
|
|
160
|
+
? {}
|
|
161
|
+
: structuredClone(this.additionalRenderParameters)),
|
|
162
|
+
...additionalParams,
|
|
163
|
+
messages,
|
|
164
|
+
...removeUndefinedFields({ tools })
|
|
165
|
+
});
|
|
166
|
+
if (eraseRenderedJinjaFromId != null) {
|
|
167
|
+
const eraseIndex = res.lastIndexOf(eraseRenderedJinjaFromId);
|
|
168
|
+
if (eraseIndex >= 0)
|
|
169
|
+
res = res.slice(0, eraseIndex + eraseRenderedJinjaFromId.length);
|
|
170
|
+
}
|
|
171
|
+
// attempt to remove the ID pattern from the output
|
|
172
|
+
if (wipeFunctionCallIds === "align")
|
|
173
|
+
res = res
|
|
174
|
+
.replaceAll(/,\s*"(tool_call_id|call_id|id)":\s*"fc_1_0001"/g, "")
|
|
175
|
+
.replaceAll(/"(tool_call_id|call_id|id)":\s*"fc_1_0001"\s*,/g, "");
|
|
176
|
+
return res;
|
|
177
|
+
};
|
|
178
|
+
return tryMatrix({
|
|
179
|
+
convertSystemMessagesToUserMessagesFormat: getConvertUnsupportedSystemMessagesToUserMessagesTryOptions(this.convertUnsupportedSystemMessagesToUserMessages),
|
|
180
|
+
wipeFunctionCallIds: [true, "align", false]
|
|
181
|
+
}, ({ convertSystemMessagesToUserMessagesFormat, wipeFunctionCallIds }) => {
|
|
182
|
+
return render(convertSystemMessagesToUserMessagesFormat, wipeFunctionCallIds);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
functionCallSettings = extractedSettings.settings;
|
|
187
|
+
if (functionCallSettings != null) {
|
|
188
|
+
this._usingJinjaFunctionCallTemplate = true;
|
|
189
|
+
this._stringifyFunctionParams = extractedSettings.stringifyParams;
|
|
190
|
+
this._stringifyFunctionResult = extractedSettings.stringifyResult;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
// do nothing
|
|
195
|
+
}
|
|
196
|
+
if (functionCallSettings == null && _requireFunctionCallSettingsExtraction)
|
|
197
|
+
throw new Error("failed to extract function call settings from the Jinja template");
|
|
198
|
+
}
|
|
199
|
+
this.settings = {
|
|
200
|
+
...this.settings,
|
|
201
|
+
functions: functionCallSettings ?? ChatWrapper.defaultSettings.functions
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Whether the function call syntax settings were extracted from the given Jinja template.
|
|
206
|
+
*
|
|
207
|
+
* The function call syntax settings can be accessed using the `.settings.functions` property.
|
|
208
|
+
*/
|
|
209
|
+
get usingJinjaFunctionCallTemplate() {
|
|
210
|
+
return this._usingJinjaFunctionCallTemplate;
|
|
74
211
|
}
|
|
75
212
|
generateContextState({ chatHistory, availableFunctions, documentFunctionParams }) {
|
|
76
|
-
const
|
|
77
|
-
|
|
213
|
+
const { contextText, stopGenerationTriggers, ignoreStartText, functionCall, transformedSystemMessagesToUserMessages } = this._generateContextState({
|
|
214
|
+
chatHistory, availableFunctions, documentFunctionParams,
|
|
215
|
+
endJinjaMessagesWithUserMessage: this._endJinjaMessagesWithUserMessage
|
|
78
216
|
});
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
217
|
+
return { contextText, stopGenerationTriggers, ignoreStartText, functionCall, transformedSystemMessagesToUserMessages };
|
|
218
|
+
}
|
|
219
|
+
addAvailableFunctionsSystemMessageToHistory(history, availableFunctions, options = {}) {
|
|
220
|
+
if (this._usingJinjaFunctionCallTemplate)
|
|
221
|
+
return history;
|
|
222
|
+
return super.addAvailableFunctionsSystemMessageToHistory(history, availableFunctions, options);
|
|
223
|
+
}
|
|
224
|
+
generateFunctionCall(name, params) {
|
|
225
|
+
if (!this._stringifyFunctionParams)
|
|
226
|
+
return super.generateFunctionCall(name, params);
|
|
227
|
+
const emptyCallParamsPlaceholder = this.settings.functions.call.emptyCallParamsPlaceholder;
|
|
228
|
+
return LlamaText([
|
|
229
|
+
this.settings.functions.call.prefix,
|
|
230
|
+
name,
|
|
231
|
+
this.settings.functions.call.paramsPrefix,
|
|
232
|
+
(params === undefined
|
|
233
|
+
? (emptyCallParamsPlaceholder === undefined || emptyCallParamsPlaceholder === "")
|
|
234
|
+
? ""
|
|
235
|
+
: JSON.stringify(jsonDumps(emptyCallParamsPlaceholder))
|
|
236
|
+
: JSON.stringify(jsonDumps(params))),
|
|
237
|
+
this.settings.functions.call.suffix
|
|
238
|
+
]);
|
|
239
|
+
}
|
|
240
|
+
generateFunctionCallResult(functionName, functionParams, result) {
|
|
241
|
+
const resolveParameters = (text) => {
|
|
242
|
+
return LlamaText(text)
|
|
243
|
+
.mapValues((value) => {
|
|
244
|
+
if (typeof value !== "string")
|
|
245
|
+
return value;
|
|
246
|
+
const funcParamsText = functionParams === undefined
|
|
247
|
+
? ""
|
|
248
|
+
: jsonDumps(functionParams);
|
|
249
|
+
return value
|
|
250
|
+
.replaceAll("{{functionName}}", functionName)
|
|
251
|
+
.replaceAll("{{functionParams}}", (this._stringifyFunctionParams && funcParamsText !== "")
|
|
252
|
+
? JSON.stringify(funcParamsText)
|
|
253
|
+
: funcParamsText);
|
|
92
254
|
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
255
|
+
};
|
|
256
|
+
const resultText = result === undefined
|
|
257
|
+
? "void"
|
|
258
|
+
: jsonDumps(result);
|
|
259
|
+
return LlamaText([
|
|
260
|
+
resolveParameters(this.settings.functions.result.prefix),
|
|
261
|
+
((this._stringifyFunctionResult && result !== undefined)
|
|
262
|
+
? JSON.stringify(resultText)
|
|
263
|
+
: resultText),
|
|
264
|
+
resolveParameters(this.settings.functions.result.suffix)
|
|
265
|
+
]);
|
|
266
|
+
}
|
|
267
|
+
/** @internal */
|
|
268
|
+
_generateContextState({ chatHistory, availableFunctions, documentFunctionParams, endJinjaMessagesWithUserMessage }) {
|
|
269
|
+
return tryMatrix({
|
|
270
|
+
convertSystemMessagesToUserMessagesFormat: getConvertUnsupportedSystemMessagesToUserMessagesTryOptions(this.convertUnsupportedSystemMessagesToUserMessages),
|
|
271
|
+
endJinjaMessagesWithUserMessage: endJinjaMessagesWithUserMessage == null
|
|
272
|
+
? [false, true]
|
|
273
|
+
: [endJinjaMessagesWithUserMessage],
|
|
274
|
+
useMessagesWithEmbeddedTools: this._usingJinjaFunctionCallTemplate
|
|
275
|
+
? [undefined, true]
|
|
276
|
+
: [undefined]
|
|
277
|
+
}, ({ useMessagesWithEmbeddedTools, endJinjaMessagesWithUserMessage, convertSystemMessagesToUserMessagesFormat }) => {
|
|
278
|
+
return this._generateContextText(chatHistory, {
|
|
279
|
+
convertSystemMessagesToUserMessagesFormat, availableFunctions, documentFunctionParams,
|
|
280
|
+
endJinjaMessagesWithUserMessage,
|
|
281
|
+
useMessagesWithEmbeddedTools
|
|
97
282
|
});
|
|
98
|
-
}
|
|
283
|
+
});
|
|
99
284
|
}
|
|
100
285
|
/** @internal */
|
|
101
|
-
|
|
286
|
+
_transformChatHistory(history, { convertSystemMessagesToUserMessagesFormat, availableFunctions, documentFunctionParams = true, joinAdjacentMessagesOfTheSameType = this.joinAdjacentMessagesOfTheSameType }) {
|
|
287
|
+
const historyWithFunctions = this.addAvailableFunctionsSystemMessageToHistory(history, availableFunctions, {
|
|
288
|
+
documentParams: documentFunctionParams
|
|
289
|
+
});
|
|
102
290
|
let transformedSystemMessagesToUserMessages = false;
|
|
103
291
|
const transformedHistory = convertSystemMessagesToUserMessagesFormat == null
|
|
104
|
-
?
|
|
105
|
-
:
|
|
292
|
+
? historyWithFunctions
|
|
293
|
+
: historyWithFunctions.map((item) => {
|
|
106
294
|
if (item.type === "system") {
|
|
107
295
|
transformedSystemMessagesToUserMessages = true;
|
|
108
296
|
return {
|
|
@@ -112,58 +300,89 @@ export class JinjaTemplateChatWrapper extends ChatWrapper {
|
|
|
112
300
|
}
|
|
113
301
|
return item;
|
|
114
302
|
});
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
else
|
|
303
|
+
return {
|
|
304
|
+
transformedHistory: joinAdjacentMessagesOfTheSameType
|
|
305
|
+
? squashChatHistoryItems(transformedHistory)
|
|
306
|
+
: transformedHistory,
|
|
307
|
+
transformedSystemMessagesToUserMessages
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/** @internal */
|
|
311
|
+
_generateContextText(history, { convertSystemMessagesToUserMessagesFormat, availableFunctions, documentFunctionParams = true, endJinjaMessagesWithUserMessage, useMessagesWithEmbeddedTools = false }) {
|
|
312
|
+
const { transformedSystemMessagesToUserMessages, transformedHistory } = this._transformChatHistory(history, { convertSystemMessagesToUserMessagesFormat, availableFunctions, documentFunctionParams });
|
|
313
|
+
const generateMessagesWithEmbeddedTools = (chatHistory) => ({
|
|
314
|
+
messages: chatHistory.map((item) => {
|
|
315
|
+
if (item.type === "system")
|
|
316
|
+
return {
|
|
317
|
+
role: "system",
|
|
318
|
+
content: LlamaText.fromJSON(item.text)
|
|
319
|
+
};
|
|
320
|
+
else if (item.type === "user")
|
|
321
|
+
return {
|
|
322
|
+
role: "user",
|
|
323
|
+
content: LlamaText(item.text)
|
|
324
|
+
};
|
|
325
|
+
else if (item.type === "model")
|
|
326
|
+
return {
|
|
327
|
+
role: "assistant",
|
|
328
|
+
content: this.generateModelResponseText(item.response)
|
|
329
|
+
};
|
|
143
330
|
void item;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
331
|
+
return { role: "user", content: LlamaText("") };
|
|
332
|
+
}),
|
|
333
|
+
tools: undefined
|
|
334
|
+
});
|
|
335
|
+
const generateMessagesWithTools = (chatHistory) => (fromChatHistoryToIntermediateOpenAiMessages({
|
|
336
|
+
chatHistory,
|
|
337
|
+
chatWrapperSettings: this.settings,
|
|
338
|
+
useRawValues: false,
|
|
339
|
+
functions: (availableFunctions != null && !documentFunctionParams)
|
|
340
|
+
? Object.fromEntries(Object.entries(availableFunctions)
|
|
341
|
+
.map(([funcName, { description, ...func }]) => [funcName, func]))
|
|
342
|
+
: availableFunctions,
|
|
343
|
+
stringifyFunctionParams: this._stringifyFunctionParams,
|
|
344
|
+
stringifyFunctionResults: this._stringifyFunctionResult,
|
|
345
|
+
combineModelMessageAndToolCalls: this._combineJinjaModelMessageAndToolCalls
|
|
346
|
+
}));
|
|
347
|
+
const lastItemIsModelMessage = transformedHistory.at(-1)?.type === "model";
|
|
348
|
+
const { messages: intermediateMessages, tools } = this._usingJinjaFunctionCallTemplate
|
|
349
|
+
? useMessagesWithEmbeddedTools
|
|
350
|
+
? {
|
|
351
|
+
messages: generateMessagesWithEmbeddedTools(transformedHistory).messages,
|
|
352
|
+
tools: generateMessagesWithTools(transformedHistory).tools
|
|
353
|
+
}
|
|
354
|
+
: generateMessagesWithTools(transformedHistory)
|
|
355
|
+
: generateMessagesWithEmbeddedTools(transformedHistory);
|
|
356
|
+
const idsGenerator = new UniqueIdGenerator(this.template + this.modelRoleName + this.userRoleName + this.systemRoleName +
|
|
357
|
+
(convertSystemMessagesToUserMessagesFormat ?? "") +
|
|
358
|
+
intermediateMessages.map(({ content }) => (content?.toString() ?? "")).join("\n\n"));
|
|
149
359
|
const jinjaItems = [];
|
|
150
360
|
const jinjaRoleMap = {
|
|
151
361
|
system: this.systemRoleName,
|
|
152
362
|
user: this.userRoleName,
|
|
153
|
-
|
|
363
|
+
assistant: this.modelRoleName,
|
|
364
|
+
tool: "tool"
|
|
154
365
|
};
|
|
155
366
|
const idToContent = new Map();
|
|
156
367
|
const modelMessageIds = new Set();
|
|
157
368
|
const messageIds = new Set();
|
|
158
|
-
for (const
|
|
159
|
-
|
|
369
|
+
for (const intermediateMessage of intermediateMessages) {
|
|
370
|
+
if (intermediateMessage.content == null) {
|
|
371
|
+
jinjaItems.push({
|
|
372
|
+
...intermediateMessage,
|
|
373
|
+
role: jinjaRoleMap[intermediateMessage.role] ?? intermediateMessage.role
|
|
374
|
+
});
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const id = idsGenerator.generateId(intermediateMessage.role === "tool");
|
|
160
378
|
messageIds.add(id);
|
|
161
|
-
idToContent.set(id,
|
|
379
|
+
idToContent.set(id, LlamaText(intermediateMessage.content));
|
|
162
380
|
jinjaItems.push({
|
|
163
|
-
|
|
381
|
+
...intermediateMessage,
|
|
382
|
+
role: jinjaRoleMap[intermediateMessage.role] ?? intermediateMessage.role,
|
|
164
383
|
content: id
|
|
165
384
|
});
|
|
166
|
-
if (
|
|
385
|
+
if (intermediateMessage.role === "assistant" || intermediateMessage.role === "tool")
|
|
167
386
|
modelMessageIds.add(id);
|
|
168
387
|
}
|
|
169
388
|
const bosTokenId = idsGenerator.generateId();
|
|
@@ -172,41 +391,39 @@ export class JinjaTemplateChatWrapper extends ChatWrapper {
|
|
|
172
391
|
idToContent.set(bosTokenId, new SpecialToken("BOS"));
|
|
173
392
|
idToContent.set(eosTokenId, new SpecialToken("EOS"));
|
|
174
393
|
idToContent.set(eotTokenId, new SpecialToken("EOT"));
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
394
|
+
const lastJinjaItem = jinjaItems.at(-1);
|
|
395
|
+
let eraseRenderedJinjaFromId;
|
|
396
|
+
if (endJinjaMessagesWithUserMessage && lastJinjaItem?.role === this.modelRoleName &&
|
|
397
|
+
typeof lastJinjaItem.content === "string" &&
|
|
398
|
+
lastJinjaItem.content.length > 0 &&
|
|
399
|
+
(lastJinjaItem["tool_calls"] == null ||
|
|
400
|
+
lastJinjaItem["tool_calls"]?.length === 0)) {
|
|
401
|
+
eraseRenderedJinjaFromId = lastJinjaItem.content;
|
|
402
|
+
jinjaItems.push({
|
|
403
|
+
role: this.userRoleName,
|
|
404
|
+
content: idsGenerator.generateId()
|
|
405
|
+
});
|
|
187
406
|
}
|
|
188
407
|
const renderJinjaText = () => {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
})
|
|
209
|
-
]);
|
|
408
|
+
let res = tryMatrix({
|
|
409
|
+
options: [{}, { "add_generation_prompt": true }]
|
|
410
|
+
}, ({ options }) => (this._jinjaTemplate.render({
|
|
411
|
+
...(this.additionalRenderParameters == null
|
|
412
|
+
? {}
|
|
413
|
+
: structuredClone(this.additionalRenderParameters)),
|
|
414
|
+
messages: jinjaItems,
|
|
415
|
+
...removeUndefinedFields({ tools }),
|
|
416
|
+
"bos_token": bosTokenId,
|
|
417
|
+
"eos_token": eosTokenId,
|
|
418
|
+
"eot_token": eotTokenId,
|
|
419
|
+
...options
|
|
420
|
+
})));
|
|
421
|
+
if (eraseRenderedJinjaFromId != null) {
|
|
422
|
+
const eraseIndex = res.lastIndexOf(eraseRenderedJinjaFromId);
|
|
423
|
+
if (eraseIndex >= 0)
|
|
424
|
+
res = res.slice(0, eraseIndex + eraseRenderedJinjaFromId.length);
|
|
425
|
+
}
|
|
426
|
+
return res;
|
|
210
427
|
};
|
|
211
428
|
const validateThatAllMessageIdsAreUsed = (parts) => {
|
|
212
429
|
const messageIdsLeft = new Set(messageIds);
|
|
@@ -290,48 +507,41 @@ export class JinjaTemplateChatWrapper extends ChatWrapper {
|
|
|
290
507
|
}))
|
|
291
508
|
])
|
|
292
509
|
],
|
|
293
|
-
transformedSystemMessagesToUserMessages
|
|
510
|
+
transformedSystemMessagesToUserMessages,
|
|
511
|
+
endJinjaMessagesWithUserMessage
|
|
294
512
|
};
|
|
295
513
|
}
|
|
296
514
|
/**
|
|
297
515
|
* Validate that this Jinja template can be rendered
|
|
298
516
|
* @internal
|
|
299
517
|
*/
|
|
300
|
-
_runSanityTest() {
|
|
518
|
+
_runSanityTest(needsToEndJinjaMessagesWithUserMessage = false) {
|
|
301
519
|
try {
|
|
302
520
|
let supportsSystemMessages = true;
|
|
303
521
|
for (const chatHistory of chatHistoriesForSanityTest) {
|
|
304
|
-
const { transformedSystemMessagesToUserMessages } = this.
|
|
522
|
+
const { transformedSystemMessagesToUserMessages, endJinjaMessagesWithUserMessage: endedJinjaMessagesWithUserMessage } = this._generateContextState({
|
|
523
|
+
chatHistory,
|
|
524
|
+
endJinjaMessagesWithUserMessage: needsToEndJinjaMessagesWithUserMessage
|
|
525
|
+
? true
|
|
526
|
+
: undefined
|
|
527
|
+
});
|
|
305
528
|
if (transformedSystemMessagesToUserMessages)
|
|
306
529
|
supportsSystemMessages = false;
|
|
530
|
+
if (!needsToEndJinjaMessagesWithUserMessage && endedJinjaMessagesWithUserMessage) {
|
|
531
|
+
if (chatHistory !== chatHistoriesForSanityTest[0])
|
|
532
|
+
// validate tha this doesn't break the template
|
|
533
|
+
return this._runSanityTest(true);
|
|
534
|
+
else
|
|
535
|
+
needsToEndJinjaMessagesWithUserMessage = true;
|
|
536
|
+
}
|
|
307
537
|
}
|
|
308
|
-
return { supportsSystemMessages };
|
|
538
|
+
return { supportsSystemMessages, needsToEndJinjaMessagesWithUserMessage };
|
|
309
539
|
}
|
|
310
540
|
catch (err) {
|
|
311
541
|
throw new Error("The provided Jinja template failed the sanity test: " + String(err) + ". Inspect the Jinja template to find out what went wrong");
|
|
312
542
|
}
|
|
313
543
|
}
|
|
314
544
|
}
|
|
315
|
-
class UniqueTemplateId {
|
|
316
|
-
antiText;
|
|
317
|
-
_ids = new Set();
|
|
318
|
-
constructor(antiText) {
|
|
319
|
-
this.antiText = antiText;
|
|
320
|
-
}
|
|
321
|
-
generateId() {
|
|
322
|
-
let id;
|
|
323
|
-
do {
|
|
324
|
-
id = "W" + (Math.random()
|
|
325
|
-
.toString(36)
|
|
326
|
-
.slice(2)) + "W";
|
|
327
|
-
} while (this._ids.has(id) || this.antiText.includes(id));
|
|
328
|
-
this._ids.add(id);
|
|
329
|
-
return id;
|
|
330
|
-
}
|
|
331
|
-
removeId(id) {
|
|
332
|
-
this._ids.delete(id);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
545
|
function resolveConvertUnsupportedSystemMessagesToUserMessagesOption(convertUnsupportedSystemMessagesToUserMessages) {
|
|
336
546
|
if (convertUnsupportedSystemMessagesToUserMessages === false)
|
|
337
547
|
return undefined;
|
|
@@ -352,6 +562,13 @@ function resolveConvertUnsupportedSystemMessagesToUserMessagesOption(convertUnsu
|
|
|
352
562
|
};
|
|
353
563
|
return { ...defaultConvertUnsupportedSystemMessagesToUserMessagesFormat, use: "ifNeeded" };
|
|
354
564
|
}
|
|
565
|
+
function getConvertUnsupportedSystemMessagesToUserMessagesTryOptions(convertUnsupportedSystemMessagesToUserMessages) {
|
|
566
|
+
if (convertUnsupportedSystemMessagesToUserMessages == null)
|
|
567
|
+
return [undefined];
|
|
568
|
+
else if (convertUnsupportedSystemMessagesToUserMessages.use === "always")
|
|
569
|
+
return [convertUnsupportedSystemMessagesToUserMessages.format];
|
|
570
|
+
return [undefined, convertUnsupportedSystemMessagesToUserMessages.format];
|
|
571
|
+
}
|
|
355
572
|
const chatHistoriesForSanityTest = [
|
|
356
573
|
[{
|
|
357
574
|
type: "system",
|