1
+ /* eslint-disable no-param-reassign */
1
2
import { DBEntry } from 'electron/main/vector-database/schema'
2
3
import { FileInfoWithContent } from 'electron/main/filesystem/types'
3
4
import { generateChatName } from '@shared/utils'
@@ -77,61 +78,78 @@ export function anonymizeAgentConfigForPosthog(
77
78
78
79
const generateStringOfContextItemsForPrompt = ( contextItems : DBEntry [ ] | FileInfoWithContent [ ] ) : string => {
79
80
const contextString = contextItems . map ( ( item ) => JSON . stringify ( item , null , 2 ) ) . join ( '\n\n' )
80
- return `<context>${ contextString } </context>`
81
+ return `${ contextString } `
82
+ }
83
+
84
+ const replaceTemplatePlaceholders = ( content : string , userQuery : string ) => {
85
+ const now = new Date ( )
86
+ const today = format ( now , "yyyy-MM-dd'T'HH:mm:ss.SSSxxx" )
87
+ return content . replace ( '{QUERY}' , userQuery ) . replace ( '{TODAY}' , today )
81
88
}
82
89
83
90
const generateMessagesFromTemplate = (
84
91
promptTemplate : PromptTemplate ,
85
- query : string ,
92
+ userQuery : string ,
86
93
contextItems : DBEntry [ ] | FileInfoWithContent [ ] ,
87
- contextString : string ,
88
94
) : ReorChatMessage [ ] => {
89
- return promptTemplate . map ( ( message ) => {
90
- const replacePlaceholders = ( content : string ) => {
91
- const now = new Date ( )
92
- const today = format ( now , "yyyy-MM-dd'T'HH:mm:ss.SSSxxx" )
93
- return content . replace ( '{QUERY}' , query ) . replace ( '{TODAY}' , today )
94
- }
95
-
96
- if ( message . role === 'system' ) {
95
+ return promptTemplate . map ( ( templateMessage ) => {
96
+ if ( templateMessage . role === 'system' ) {
97
97
return {
98
- ...message ,
99
- content : `${ replacePlaceholders ( message . content ) } \n\n ${ contextString } ` ,
98
+ ...templateMessage ,
99
+ content : `${ replaceTemplatePlaceholders ( templateMessage . content , userQuery ) } ` ,
100
100
hideMessage : true ,
101
101
}
102
102
}
103
103
104
- if ( message . role === 'user' ) {
104
+ if ( templateMessage . role === 'user' ) {
105
105
return {
106
- ...message ,
106
+ ...templateMessage ,
107
107
context : contextItems ,
108
- content : replacePlaceholders ( message . content ) ,
109
- visibleContent : query ,
108
+ content : replaceTemplatePlaceholders ( templateMessage . content , userQuery ) ,
109
+ visibleContent : userQuery ,
110
110
}
111
111
}
112
112
113
- return message
113
+ return templateMessage
114
114
} ) as ReorChatMessage [ ]
115
115
}
116
116
117
- export const doInitialRAG = async ( query : string , agentConfig : AgentConfig ) : Promise < ReorChatMessage [ ] > => {
118
- const { promptTemplate, files } = agentConfig
119
- let contextItems : DBEntry [ ] | FileInfoWithContent [ ] = [ ]
117
+ const injectContextStringIntoMessages = (
118
+ messages : ReorChatMessage [ ] ,
119
+ contextItems : DBEntry [ ] | FileInfoWithContent [ ] ,
120
+ contextString : string ,
121
+ ) : ReorChatMessage [ ] => {
122
+ const lastUserMessage = messages . findLast ( ( message ) => message . role === 'user' )
123
+ if ( lastUserMessage ) {
124
+ lastUserMessage . content = `The context retrieved from the user's knowledge base for the query is: ${ contextString } \n\n${ lastUserMessage . content } `
125
+ lastUserMessage . context = contextItems
126
+ }
127
+ return messages
128
+ }
129
+
130
+ const retrieveContextItems = async (
131
+ query : string ,
132
+ agentConfig : AgentConfig ,
133
+ ) : Promise < DBEntry [ ] | FileInfoWithContent [ ] > => {
134
+ const { files } = agentConfig
120
135
121
136
if ( files . length > 0 ) {
122
- contextItems = await window . fileSystem . getFiles ( files )
123
- } else if ( agentConfig . dbSearchFilters ) {
124
- contextItems = await retreiveFromVectorDB ( query , agentConfig . dbSearchFilters )
137
+ return window . fileSystem . getFiles ( files )
125
138
}
126
139
127
- const contextString = generateStringOfContextItemsForPrompt ( contextItems )
128
- const messages = generateMessagesFromTemplate ( promptTemplate , query , contextItems , contextString )
140
+ if ( agentConfig . dbSearchFilters ) {
141
+ return retreiveFromVectorDB ( query , agentConfig . dbSearchFilters )
142
+ }
129
143
130
- return messages
144
+ return [ ]
131
145
}
132
146
133
147
export const generateInitialChat = async ( userTextFieldInput : string , agentConfig : AgentConfig ) : Promise < Chat > => {
134
- const ragMessages = await doInitialRAG ( userTextFieldInput ?? '' , agentConfig )
148
+ const contextItems = await retrieveContextItems ( userTextFieldInput ?? '' , agentConfig )
149
+
150
+ const contextString = generateStringOfContextItemsForPrompt ( contextItems )
151
+ const messages = generateMessagesFromTemplate ( agentConfig . promptTemplate , userTextFieldInput ?? '' , contextItems )
152
+ const ragMessages = injectContextStringIntoMessages ( messages , contextItems , contextString )
135
153
136
154
return {
137
155
id : Date . now ( ) . toString ( ) ,
@@ -141,6 +159,32 @@ export const generateInitialChat = async (userTextFieldInput: string, agentConfi
141
159
toolDefinitions : agentConfig . toolDefinitions ,
142
160
}
143
161
}
162
+
163
+ const generateFollowUpChat = async (
164
+ currentChat : Chat | undefined ,
165
+ userTextFieldInput : string ,
166
+ agentConfig : AgentConfig | undefined ,
167
+ ) : Promise < Chat > => {
168
+ if ( ! currentChat ) {
169
+ throw new Error ( 'Current chat is required' )
170
+ }
171
+ currentChat . messages . push ( {
172
+ role : 'user' ,
173
+ visibleContent : userTextFieldInput ,
174
+ content : `The user's query is: ${ userTextFieldInput } ` ,
175
+ context : [ ] ,
176
+ } )
177
+
178
+ if ( agentConfig ) {
179
+ const contextItems = await retrieveContextItems ( userTextFieldInput ?? '' , agentConfig )
180
+ const contextString = generateStringOfContextItemsForPrompt ( contextItems )
181
+ currentChat . messages = injectContextStringIntoMessages ( currentChat . messages , contextItems , contextString )
182
+ currentChat . toolDefinitions = agentConfig . toolDefinitions
183
+ }
184
+
185
+ return currentChat
186
+ }
187
+
144
188
export const appendToOrCreateChat = async (
145
189
currentChat : Chat | undefined ,
146
190
userTextFieldInput : string ,
@@ -160,11 +204,7 @@ export const appendToOrCreateChat = async (
160
204
...anonymizedAgentConfig ,
161
205
} )
162
206
} else {
163
- outputChat . messages . push ( {
164
- role : 'user' ,
165
- content : userTextFieldInput ,
166
- context : [ ] ,
167
- } )
207
+ outputChat = await generateFollowUpChat ( outputChat , userTextFieldInput , agentConfig )
168
208
posthog . capture ( 'follow_up_chat_message_submitted' , {
169
209
chatId : outputChat ?. id ,
170
210
chatLength : outputChat ?. messages . length ,
0 commit comments