@@ -330,18 +330,26 @@ export type LLamaChatCompletePromptOptions = {
330
330
enabled ?: "auto" | boolean ,
331
331
332
332
/**
333
- * The user prompt to give the model for the completion.
333
+ * The messages to append to the chat history to generate a completion as a model response .
334
334
*
335
- * Defaults to `"What may I say next?"`
336
- */
337
- userPrompt ?: string ,
338
-
339
- /**
340
- * The prefix to supply a model message with for the completion.
335
+ * If the last message is a model message, the prompt will be pushed to it for the completion,
336
+ * otherwise a new model message will be added with the prompt.
341
337
*
342
- * Defaults to `"Here's a possible reply from you:\t"`
338
+ * It must contain a user message or a system message before the model message.
339
+ *
340
+ * Default to:
341
+ * ```ts
342
+ * [
343
+ * {
344
+ * type: "system",
345
+ * text: "For your next response predict what the user may send next. No yapping, no whitespace. Match the user's language and tone."
346
+ * },
347
+ * {type: "user", text: ""},
348
+ * {type: "model", response: [""]}
349
+ * ]
350
+ * ```
343
351
*/
344
- modelPrefix ?: string
352
+ appendedMessages ?: ChatHistoryItem [ ]
345
353
}
346
354
} ;
347
355
@@ -391,8 +399,14 @@ export type LlamaChatSessionRepeatPenalty = {
391
399
392
400
const defaultCompleteAsModel = {
393
401
enabled : "auto" ,
394
- userPrompt : "What may I say next?" ,
395
- modelPrefix : "Here's a possible reply from you:\t"
402
+ appendedMessages : [
403
+ {
404
+ type : "system" ,
405
+ text : "For your next response predict what the user may send next. No yapping, no whitespace. Match the user's language and tone."
406
+ } ,
407
+ { type : "user" , text : "" } ,
408
+ { type : "model" , response : [ "" ] }
409
+ ]
396
410
} as const satisfies LLamaChatCompletePromptOptions [ "completeAsModel" ] ;
397
411
398
412
/**
@@ -928,19 +942,56 @@ export class LlamaChatSession {
928
942
throw new DisposedError ( ) ;
929
943
930
944
if ( shouldCompleteAsModel ) {
931
- const completeAsModelUserPrompt = ( typeof completeAsModel == "boolean" || completeAsModel === "auto" )
932
- ? defaultCompleteAsModel . userPrompt
933
- : completeAsModel ?. userPrompt ?? defaultCompleteAsModel . userPrompt ;
934
- const completeAsModelMessagePrefix = ( typeof completeAsModel == "boolean" || completeAsModel === "auto" )
935
- ? defaultCompleteAsModel . modelPrefix
936
- : completeAsModel ?. modelPrefix ?? defaultCompleteAsModel . modelPrefix ;
945
+ const messagesToAppendOption = ( typeof completeAsModel == "boolean" || completeAsModel === "auto" )
946
+ ? defaultCompleteAsModel . appendedMessages
947
+ : completeAsModel ?. appendedMessages ?? defaultCompleteAsModel . appendedMessages ;
948
+
949
+ const messagesToAppend = messagesToAppendOption . length === 0
950
+ ? defaultCompleteAsModel . appendedMessages
951
+ : messagesToAppendOption ;
952
+
953
+ const addMessageToChatHistory = ( chatHistory : ChatHistoryItem [ ] ) : {
954
+ history : ChatHistoryItem [ ] ,
955
+ addedCount : number
956
+ } => {
957
+ const newHistory = chatHistory . slice ( ) ;
958
+ if ( messagesToAppend . at ( 0 ) ?. type === "model" )
959
+ newHistory . push ( { type : "user" , text : "" } ) ;
960
+
961
+ for ( let i = 0 ; i < messagesToAppend . length ; i ++ ) {
962
+ const item = messagesToAppend [ i ] ;
963
+ const isLastItem = i === messagesToAppend . length - 1 ;
964
+
965
+ if ( item == null )
966
+ continue ;
967
+
968
+ if ( isLastItem && item . type === "model" ) {
969
+ const newResponse = item . response . slice ( ) ;
970
+ if ( typeof newResponse . at ( - 1 ) === "string" )
971
+ newResponse . push ( ( newResponse . pop ( ) ! as string ) + prompt )
972
+ else
973
+ newResponse . push ( prompt ) ;
974
+
975
+ newHistory . push ( {
976
+ type : "model" ,
977
+ response : newResponse
978
+ } )
979
+ } else
980
+ newHistory . push ( item ) ;
981
+ }
982
+
983
+ if ( messagesToAppend . at ( - 1 ) ?. type !== "model" )
984
+ newHistory . push ( { type : "model" , response : [ prompt ] } ) ;
985
+
986
+ return {
987
+ history : newHistory ,
988
+ addedCount : newHistory . length - chatHistory . length
989
+ } ;
990
+ } ;
937
991
992
+ const { history : messagesWithPrompt , addedCount} = addMessageToChatHistory ( this . _chatHistory ) ;
938
993
const { response, lastEvaluation, metadata} = await this . _chat . generateResponse (
939
- [
940
- ...asWithLastUserMessageRemoved ( this . _chatHistory ) ,
941
- { type : "user" , text : completeAsModelUserPrompt } ,
942
- { type : "model" , response : [ completeAsModelMessagePrefix + prompt ] }
943
- ] as ChatHistoryItem [ ] ,
994
+ messagesWithPrompt ,
944
995
{
945
996
abortOnNonText : true ,
946
997
functions,
@@ -968,11 +1019,7 @@ export class LlamaChatSession {
968
1019
lastEvaluationContextWindow : {
969
1020
history : this . _lastEvaluation ?. contextWindow == null
970
1021
? undefined
971
- : [
972
- ...asWithLastUserMessageRemoved ( this . _lastEvaluation ?. contextWindow ) ,
973
- { type : "user" , text : completeAsModelUserPrompt } ,
974
- { type : "model" , response : [ completeAsModelMessagePrefix + prompt ] }
975
- ] as ChatHistoryItem [ ] ,
1022
+ : addMessageToChatHistory ( this . _lastEvaluation ?. contextWindow ) . history ,
976
1023
minimumOverlapPercentageToPreventContextShift : 0.8
977
1024
}
978
1025
}
@@ -981,7 +1028,7 @@ export class LlamaChatSession {
981
1028
982
1029
this . _lastEvaluation = {
983
1030
cleanHistory : this . _chatHistory ,
984
- contextWindow : asWithLastUserMessageRemoved ( asWithLastModelMessageRemoved ( lastEvaluation . contextWindow ) ) ,
1031
+ contextWindow : lastEvaluation . contextWindow . slice ( 0 , - addedCount ) ,
985
1032
contextShiftMetadata : lastEvaluation . contextShiftMetadata
986
1033
} ;
987
1034
this . _canUseContextWindowForCompletion = this . _chatHistory . at ( - 1 ) ?. type === "user" ;
@@ -1183,18 +1230,3 @@ function asWithLastUserMessageRemoved(chatHistory?: ChatHistoryItem[]) {
1183
1230
1184
1231
return newChatHistory ;
1185
1232
}
1186
-
1187
-
1188
- function asWithLastModelMessageRemoved ( chatHistory : ChatHistoryItem [ ] ) : ChatHistoryItem [ ] ;
1189
- function asWithLastModelMessageRemoved ( chatHistory : ChatHistoryItem [ ] | undefined ) : ChatHistoryItem [ ] | undefined ;
1190
- function asWithLastModelMessageRemoved ( chatHistory ?: ChatHistoryItem [ ] ) {
1191
- if ( chatHistory == null )
1192
- return chatHistory ;
1193
-
1194
- const newChatHistory = chatHistory . slice ( ) ;
1195
-
1196
- while ( newChatHistory . at ( - 1 ) ?. type === "model" )
1197
- newChatHistory . pop ( ) ;
1198
-
1199
- return newChatHistory ;
1200
- }
0 commit comments