Skip to content

Commit 053c0c4

Browse files
committed
fix(ai): amélioration de !useLLM avec la possibilité d'utiliser l'option !noStream pour ne pas streamer la réponse du LLM, mais l'afficher d'un coup
1 parent d7d7bd4 commit 053c0c4

5 files changed

Lines changed: 57 additions & 37 deletions

File tree

app/js/ai/getAnswerFromLLM.mjs

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,18 @@ export function getAnswerFromLLM(chatbot, userPrompt, options) {
4848
let messageElement = options && options.messageElement;
4949
let container = options && options.container;
5050
const inline = options && options.inline;
51+
let shouldStreamLLMresponse = true;
52+
if (
53+
yaml.useLLM.stream === false ||
54+
(options && options.shouldStreamLLMresponse === false)
55+
) {
56+
shouldStreamLLMresponse = false;
57+
}
5158
return new Promise((resolve) => {
5259
// Configuration de l'accès au LLM
5360
let bodyObject = {
5461
model: yaml.useLLM.model,
55-
stream: yaml.useLLM.stream === false ? false : true,
62+
stream: shouldStreamLLMresponse,
5663
max_tokens: yaml.useLLM.maxTokens,
5764
frequency_penalty: 0,
5865
presence_penalty: 0,
@@ -122,39 +129,40 @@ export function getAnswerFromLLM(chatbot, userPrompt, options) {
122129
messageElement.classList.add("bot-message");
123130
}
124131
container.appendChild(messageElement);
125-
readStreamFromLLM(response.body, messageElement, APItype).then(
126-
() => {
127-
const llmAnswer = messageElement.innerHTML;
128-
llmHistory.push({ role: "user", content: userMessage });
129-
llmHistory.push({ role: "assistant", content: llmAnswer });
130-
if (!inline) {
131-
// On récupère le contenu de la question posée au LLM
132-
let actionsLatest = chatbot.actions.pop();
133-
if (actionsLatest.startsWith("c:n")) {
134-
actionsLatest = chatbot.actions.pop();
135-
}
136-
actionsLatest = encodeString(
137-
actionsLatest.replace(/^e:/, ""),
138-
);
139-
const actionsHistory = chatbot.actions.join(`|`);
140-
const actionLlmQuestion = `llmq:${actionsLatest}`;
141-
// On récupère le contenu de la réponse générée par le LLM
142-
const actionLlmAnswer = `llmr:${encodeString(llmAnswer)}`;
143-
// On met cette question et cette réponse dans l'historique des actions
144-
chatbot.actions.push(actionLlmQuestion);
145-
chatbot.actions.push(actionLlmAnswer);
146-
// Et dans le bouton de menu du message
147-
const actionsPrefix = actionsHistory
148-
? `${actionsHistory}|`
149-
: "";
150-
const messageMenu = `<div class="messageMenu" data-actions-history="${actionsPrefix}${actionLlmQuestion}|${llmAnswer}">☰</div>`;
151-
const messageMenuElement = document.createElement("div");
152-
messageMenuElement.innerHTML = messageMenu;
153-
messageElement.appendChild(messageMenuElement);
132+
readStreamFromLLM(
133+
response.body,
134+
messageElement,
135+
APItype,
136+
options,
137+
).then(() => {
138+
const llmAnswer = messageElement.innerHTML;
139+
llmHistory.push({ role: "user", content: userMessage });
140+
llmHistory.push({ role: "assistant", content: llmAnswer });
141+
if (!inline) {
142+
// On récupère le contenu de la question posée au LLM
143+
let actionsLatest = chatbot.actions.pop();
144+
if (actionsLatest.startsWith("c:n")) {
145+
actionsLatest = chatbot.actions.pop();
154146
}
155-
resolve();
156-
},
157-
);
147+
actionsLatest = encodeString(actionsLatest.replace(/^e:/, ""));
148+
const actionsHistory = chatbot.actions.join(`|`);
149+
const actionLlmQuestion = `llmq:${actionsLatest}`;
150+
// On récupère le contenu de la réponse générée par le LLM
151+
const actionLlmAnswer = `llmr:${encodeString(llmAnswer)}`;
152+
// On met cette question et cette réponse dans l'historique des actions
153+
chatbot.actions.push(actionLlmQuestion);
154+
chatbot.actions.push(actionLlmAnswer);
155+
// Et dans le bouton de menu du message
156+
const actionsPrefix = actionsHistory
157+
? `${actionsHistory}|`
158+
: "";
159+
const messageMenu = `<div class="messageMenu" data-actions-history="${actionsPrefix}${actionLlmQuestion}|${llmAnswer}">☰</div>`;
160+
const messageMenuElement = document.createElement("div");
161+
messageMenuElement.innerHTML = messageMenu;
162+
messageElement.appendChild(messageMenuElement);
163+
}
164+
resolve();
165+
});
158166
} else {
159167
errorMessage({ container, inline });
160168
resolve();

app/js/ai/helpers/readStream.mjs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export async function readStreamFromLLM(
7474
streamableObject,
7575
chatMessage,
7676
APItype,
77+
options,
7778
) {
7879
let incompleteChunkBuffer = "";
7980
const LLM_MAX_PROCESSING_TIME = yaml.useLLM.maxProcessingTime;
@@ -107,8 +108,13 @@ export async function readStreamFromLLM(
107108
if (value) {
108109
const chunkString = new TextDecoder().decode(value);
109110

110-
const isStreamMode =
111-
yaml.useLLM && yaml.useLLM.stream === false ? false : true;
111+
let isStreamMode = true;
112+
if (
113+
(yaml.useLLM && yaml.useLLM.stream === false) ||
114+
(options && options.shouldStreamLLMresponse === false)
115+
) {
116+
isStreamMode = false;
117+
}
112118
const shouldSimulateStream =
113119
yaml.useLLM && yaml.useLLM.simulateStream === true;
114120

app/js/markdown/custom/directives/useLLM/processMessageWithPrompt.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export async function processMessageWithPrompt(
4040
let RAGprompt = "";
4141
// Gestion de l'historique des échanges avec le LLM
4242
let shouldUseConversationHistory = false;
43+
let shouldStreamLLMresponse = true;
4344
if (content.includes("!useHistory")) {
4445
shouldUseConversationHistory = true;
4546
content = content.replace("!useHistory", "");
@@ -51,6 +52,10 @@ export async function processMessageWithPrompt(
5152
RAGinformations = promptWithRag.RAGinformations;
5253
RAGprompt = promptWithRag.RAGprompt;
5354
}
55+
if (content.includes("!noStream")) {
56+
shouldStreamLLMresponse = false;
57+
content = content.replace("!noStream", "");
58+
}
5459

5560
// On vérifie si l'élément précédent dans la séquence se finit par un élément html ouvert qui n'a pas été encore fermé
5661
const previousSection = sequence[i - 1];
@@ -69,6 +74,7 @@ export async function processMessageWithPrompt(
6974
container: container,
7075
inline: true,
7176
useConversationHistory: shouldUseConversationHistory,
77+
shouldStreamLLMresponse: shouldStreamLLMresponse,
7278
});
7379
} else if (type === "markdown") {
7480
// Traitement des blocs conditionnels qui restent à interpréter au moment de l'affichage du message

app/script.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/script.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)