Spaces:
Sleeping
Sleeping
| import { ResearcherOutput, SearchAgentInput } from './types'; | |
| import SessionManager from '@/lib/session'; | |
| import { classify } from './classifier'; | |
| import Researcher from './researcher'; | |
| import { getWriterPrompt } from '@/lib/prompts/search/writer'; | |
| import { WidgetExecutor } from './widgets'; | |
| class APISearchAgent { | |
| async searchAsync(session: SessionManager, input: SearchAgentInput) { | |
| const classification = await classify({ | |
| chatHistory: input.chatHistory, | |
| enabledSources: input.config.sources, | |
| query: input.followUp, | |
| llm: input.config.llm, | |
| }); | |
| const widgetPromise = WidgetExecutor.executeAll({ | |
| classification, | |
| chatHistory: input.chatHistory, | |
| followUp: input.followUp, | |
| llm: input.config.llm, | |
| }); | |
| let searchPromise: Promise<ResearcherOutput> | null = null; | |
| if (!classification.classification.skipSearch) { | |
| const researcher = new Researcher(); | |
| searchPromise = researcher.research(SessionManager.createSession(), { | |
| chatHistory: input.chatHistory, | |
| followUp: input.followUp, | |
| classification: classification, | |
| config: input.config, | |
| }); | |
| } | |
| const [widgetOutputs, searchResults] = await Promise.all([ | |
| widgetPromise, | |
| searchPromise, | |
| ]); | |
| if (searchResults) { | |
| session.emit('data', { | |
| type: 'searchResults', | |
| data: searchResults.searchFindings, | |
| }); | |
| } | |
| session.emit('data', { | |
| type: 'researchComplete', | |
| }); | |
| const finalContext = | |
| searchResults?.searchFindings | |
| .map( | |
| (f, index) => | |
| `<result index=${index + 1} title=${f.metadata.title}>${f.content}</result>`, | |
| ) | |
| .join('\n') || ''; | |
| const widgetContext = widgetOutputs | |
| .map((o) => { | |
| return `<result>${o.llmContext}</result>`; | |
| }) | |
| .join('\n-------------\n'); | |
| const finalContextWithWidgets = `<search_results note="These are the search results and assistant can cite these">\n${finalContext}\n</search_results>\n<widgets_result noteForAssistant="Its output is already showed to the user, assistant can use this information to answer the query but do not CITE this as a souce">\n${widgetContext}\n</widgets_result>`; | |
| const writerPrompt = getWriterPrompt( | |
| finalContextWithWidgets, | |
| input.config.systemInstructions, | |
| input.config.mode, | |
| ); | |
| const answerStream = input.config.llm.streamText({ | |
| messages: [ | |
| { | |
| role: 'system', | |
| content: writerPrompt, | |
| }, | |
| ...input.chatHistory, | |
| { | |
| role: 'user', | |
| content: input.followUp, | |
| }, | |
| ], | |
| }); | |
| for await (const chunk of answerStream) { | |
| session.emit('data', { | |
| type: 'response', | |
| data: chunk.contentChunk, | |
| }); | |
| } | |
| session.emit('end', {}); | |
| } | |
| } | |
| export default APISearchAgent; | |