Skip to content

Commit bc27a15

Browse files
committed
working follow up on search
1 parent a6270f0 commit bc27a15

File tree

3 files changed

+76
-36
lines changed

3 files changed

+76
-36
lines changed

src/components/Chat/ChatConfigComponents/exampleAgents.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Here are some guidelines you must follow:
1414
},
1515
{
1616
role: 'user',
17-
content: `{QUERY}`,
17+
content: `The user's query is: {QUERY}`,
1818
},
1919
]
2020

@@ -65,7 +65,7 @@ const exampleAgents: AgentConfig[] = [
6565
files: [],
6666
name: 'Default',
6767
dbSearchFilters: {
68-
limit: 30,
68+
limit: 20,
6969
minDate: undefined,
7070
maxDate: undefined,
7171
passFullNoteIntoContext: true,

src/components/File/DBResultPreview.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const DBSearchPreview: React.FC<DBSearchPreviewProps> = ({ dbResult: entr
5555

5656
return (
5757
<div
58-
className="mb-4 mt-0 max-w-full cursor-pointer overflow-hidden rounded border border-gray-600 bg-neutral-800 p-2 shadow-md transition-transform duration-300 hover:bg-neutral-500 hover:shadow-lg"
58+
className="mb-4 mt-0 max-w-full cursor-pointer overflow-hidden rounded border border-gray-600 bg-neutral-800 p-2 shadow-md transition-transform duration-300 hover:bg-neutral-700 hover:shadow-lg"
5959
onClick={() => onSelect(entry.notepath)}
6060
>
6161
<div className="text-sm text-gray-200">

src/lib/llm/chat.ts

+73-33
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-param-reassign */
12
import { DBEntry } from 'electron/main/vector-database/schema'
23
import { FileInfoWithContent } from 'electron/main/filesystem/types'
34
import { generateChatName } from '@shared/utils'
@@ -77,61 +78,78 @@ export function anonymizeAgentConfigForPosthog(
7778

7879
const generateStringOfContextItemsForPrompt = (contextItems: DBEntry[] | FileInfoWithContent[]): string => {
7980
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)
8188
}
8289

8390
const generateMessagesFromTemplate = (
8491
promptTemplate: PromptTemplate,
85-
query: string,
92+
userQuery: string,
8693
contextItems: DBEntry[] | FileInfoWithContent[],
87-
contextString: string,
8894
): 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') {
9797
return {
98-
...message,
99-
content: `${replacePlaceholders(message.content)}\n\n${contextString}`,
98+
...templateMessage,
99+
content: `${replaceTemplatePlaceholders(templateMessage.content, userQuery)}`,
100100
hideMessage: true,
101101
}
102102
}
103103

104-
if (message.role === 'user') {
104+
if (templateMessage.role === 'user') {
105105
return {
106-
...message,
106+
...templateMessage,
107107
context: contextItems,
108-
content: replacePlaceholders(message.content),
109-
visibleContent: query,
108+
content: replaceTemplatePlaceholders(templateMessage.content, userQuery),
109+
visibleContent: userQuery,
110110
}
111111
}
112112

113-
return message
113+
return templateMessage
114114
}) as ReorChatMessage[]
115115
}
116116

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
120135

121136
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)
125138
}
126139

127-
const contextString = generateStringOfContextItemsForPrompt(contextItems)
128-
const messages = generateMessagesFromTemplate(promptTemplate, query, contextItems, contextString)
140+
if (agentConfig.dbSearchFilters) {
141+
return retreiveFromVectorDB(query, agentConfig.dbSearchFilters)
142+
}
129143

130-
return messages
144+
return []
131145
}
132146

133147
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)
135153

136154
return {
137155
id: Date.now().toString(),
@@ -141,6 +159,32 @@ export const generateInitialChat = async (userTextFieldInput: string, agentConfi
141159
toolDefinitions: agentConfig.toolDefinitions,
142160
}
143161
}
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+
144188
export const appendToOrCreateChat = async (
145189
currentChat: Chat | undefined,
146190
userTextFieldInput: string,
@@ -160,11 +204,7 @@ export const appendToOrCreateChat = async (
160204
...anonymizedAgentConfig,
161205
})
162206
} else {
163-
outputChat.messages.push({
164-
role: 'user',
165-
content: userTextFieldInput,
166-
context: [],
167-
})
207+
outputChat = await generateFollowUpChat(outputChat, userTextFieldInput, agentConfig)
168208
posthog.capture('follow_up_chat_message_submitted', {
169209
chatId: outputChat?.id,
170210
chatLength: outputChat?.messages.length,

0 commit comments

Comments
 (0)