feat(search): Add searchUrl to message
This commit is contained in:
parent
641968cf6a
commit
bdace57cfd
5 changed files with 51 additions and 10 deletions
|
|
@ -66,6 +66,7 @@ const handleEmitterEvents = async (
|
||||||
let recievedMessage = '';
|
let recievedMessage = '';
|
||||||
let sources: any[] = [];
|
let sources: any[] = [];
|
||||||
let searchQuery: string | undefined;
|
let searchQuery: string | undefined;
|
||||||
|
let searchUrl: string | undefined;
|
||||||
|
|
||||||
stream.on('data', (data) => {
|
stream.on('data', (data) => {
|
||||||
const parsedData = JSON.parse(data);
|
const parsedData = JSON.parse(data);
|
||||||
|
|
@ -86,6 +87,9 @@ const handleEmitterEvents = async (
|
||||||
if (parsedData.searchQuery) {
|
if (parsedData.searchQuery) {
|
||||||
searchQuery = parsedData.searchQuery;
|
searchQuery = parsedData.searchQuery;
|
||||||
}
|
}
|
||||||
|
if (parsedData.searchUrl) {
|
||||||
|
searchUrl = parsedData.searchUrl;
|
||||||
|
}
|
||||||
|
|
||||||
writer.write(
|
writer.write(
|
||||||
encoder.encode(
|
encoder.encode(
|
||||||
|
|
@ -94,6 +98,7 @@ const handleEmitterEvents = async (
|
||||||
data: parsedData.data,
|
data: parsedData.data,
|
||||||
searchQuery: parsedData.searchQuery,
|
searchQuery: parsedData.searchQuery,
|
||||||
messageId: aiMessageId,
|
messageId: aiMessageId,
|
||||||
|
searchUrl: searchUrl,
|
||||||
}) + '\n',
|
}) + '\n',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -128,6 +133,7 @@ const handleEmitterEvents = async (
|
||||||
messageId: aiMessageId,
|
messageId: aiMessageId,
|
||||||
modelStats: modelStats,
|
modelStats: modelStats,
|
||||||
searchQuery: searchQuery,
|
searchQuery: searchQuery,
|
||||||
|
searchUrl: searchUrl,
|
||||||
}) + '\n',
|
}) + '\n',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -144,6 +150,7 @@ const handleEmitterEvents = async (
|
||||||
...(sources && sources.length > 0 && { sources }),
|
...(sources && sources.length > 0 && { sources }),
|
||||||
...(searchQuery && { searchQuery }),
|
...(searchQuery && { searchQuery }),
|
||||||
modelStats: modelStats,
|
modelStats: modelStats,
|
||||||
|
...(searchUrl && { searchUrl }),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export type Message = {
|
||||||
sources?: Document[];
|
sources?: Document[];
|
||||||
modelStats?: ModelStats;
|
modelStats?: ModelStats;
|
||||||
searchQuery?: string;
|
searchQuery?: string;
|
||||||
|
searchUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface File {
|
export interface File {
|
||||||
|
|
@ -417,7 +418,6 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
||||||
|
|
||||||
if (data.type === 'sources') {
|
if (data.type === 'sources') {
|
||||||
sources = data.data;
|
sources = data.data;
|
||||||
const searchQuery = data.searchQuery;
|
|
||||||
if (!added) {
|
if (!added) {
|
||||||
setMessages((prevMessages) => [
|
setMessages((prevMessages) => [
|
||||||
...prevMessages,
|
...prevMessages,
|
||||||
|
|
@ -427,7 +427,8 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
||||||
chatId: chatId!,
|
chatId: chatId!,
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
sources: sources,
|
sources: sources,
|
||||||
searchQuery: searchQuery,
|
searchQuery: data.searchQuery,
|
||||||
|
searchUrl: data.searchUrl,
|
||||||
createdAt: new Date(),
|
createdAt: new Date(),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
@ -486,6 +487,7 @@ const ChatWindow = ({ id }: { id?: string }) => {
|
||||||
modelStats: data.modelStats || null,
|
modelStats: data.modelStats || null,
|
||||||
// Make sure the searchQuery is preserved (if available in the message data)
|
// Make sure the searchQuery is preserved (if available in the message data)
|
||||||
searchQuery: message.searchQuery || data.searchQuery,
|
searchQuery: message.searchQuery || data.searchQuery,
|
||||||
|
searchUrl: message.searchUrl || data.searchUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
|
|
|
||||||
|
|
@ -283,9 +283,20 @@ const MessageBox = ({
|
||||||
<span className="font-medium text-black/70 dark:text-white/70">
|
<span className="font-medium text-black/70 dark:text-white/70">
|
||||||
Search query:
|
Search query:
|
||||||
</span>{' '}
|
</span>{' '}
|
||||||
<span className="text-black dark:text-white">
|
{message.searchUrl ? (
|
||||||
{message.searchQuery}
|
<a
|
||||||
</span>
|
href={message.searchUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="dark:text-white text-black hover:underline"
|
||||||
|
>
|
||||||
|
{message.searchQuery}
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<span className="text-black dark:text-white">
|
||||||
|
{message.searchQuery}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<MessageSources sources={message.sources} />
|
<MessageSources sources={message.sources} />
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ class MetaSearchAgent implements MetaSearchAgentType {
|
||||||
private config: Config;
|
private config: Config;
|
||||||
private strParser = new StringOutputParser();
|
private strParser = new StringOutputParser();
|
||||||
private searchQuery?: string;
|
private searchQuery?: string;
|
||||||
|
private searxngUrl?: string;
|
||||||
|
|
||||||
constructor(config: Config) {
|
constructor(config: Config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
@ -81,6 +82,7 @@ class MetaSearchAgent implements MetaSearchAgentType {
|
||||||
let question = this.config.summarizer
|
let question = this.config.summarizer
|
||||||
? await questionOutputParser.parse(input)
|
? await questionOutputParser.parse(input)
|
||||||
: input;
|
: input;
|
||||||
|
console.log('question', question);
|
||||||
|
|
||||||
if (question === 'not_needed') {
|
if (question === 'not_needed') {
|
||||||
return { query: '', docs: [] };
|
return { query: '', docs: [] };
|
||||||
|
|
@ -206,12 +208,15 @@ class MetaSearchAgent implements MetaSearchAgentType {
|
||||||
} else {
|
} else {
|
||||||
question = question.replace(/<think>.*?<\/think>/g, '');
|
question = question.replace(/<think>.*?<\/think>/g, '');
|
||||||
|
|
||||||
const res = await searchSearxng(question, {
|
const searxngResult = await searchSearxng(question, {
|
||||||
language: 'en',
|
language: 'en',
|
||||||
engines: this.config.activeEngines,
|
engines: this.config.activeEngines,
|
||||||
});
|
});
|
||||||
|
|
||||||
const documents = res.results.map(
|
// Store the SearXNG URL for later use in emitting to the client
|
||||||
|
this.searxngUrl = searxngResult.searchUrl;
|
||||||
|
|
||||||
|
const documents = searxngResult.results.map(
|
||||||
(result) =>
|
(result) =>
|
||||||
new Document({
|
new Document({
|
||||||
pageContent:
|
pageContent:
|
||||||
|
|
@ -447,9 +452,7 @@ class MetaSearchAgent implements MetaSearchAgentType {
|
||||||
event.event === 'on_chain_end' &&
|
event.event === 'on_chain_end' &&
|
||||||
event.name === 'FinalSourceRetriever'
|
event.name === 'FinalSourceRetriever'
|
||||||
) {
|
) {
|
||||||
// Add searchQuery to the sources data if it exists
|
|
||||||
const sourcesData = event.data.output;
|
const sourcesData = event.data.output;
|
||||||
// @ts-ignore - we added searchQuery property
|
|
||||||
if (this.searchQuery) {
|
if (this.searchQuery) {
|
||||||
emitter.emit(
|
emitter.emit(
|
||||||
'data',
|
'data',
|
||||||
|
|
@ -457,6 +460,7 @@ class MetaSearchAgent implements MetaSearchAgentType {
|
||||||
type: 'sources',
|
type: 'sources',
|
||||||
data: sourcesData,
|
data: sourcesData,
|
||||||
searchQuery: this.searchQuery,
|
searchQuery: this.searchQuery,
|
||||||
|
searchUrl: this.searxngUrl,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,12 @@ interface SearxngSearchResult {
|
||||||
iframe_src?: string;
|
iframe_src?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SearxngResponse {
|
||||||
|
results: SearxngSearchResult[];
|
||||||
|
suggestions: string[];
|
||||||
|
searchUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const searchSearxng = async (
|
export const searchSearxng = async (
|
||||||
query: string,
|
query: string,
|
||||||
opts?: SearxngSearchOptions,
|
opts?: SearxngSearchOptions,
|
||||||
|
|
@ -44,5 +50,16 @@ export const searchSearxng = async (
|
||||||
const results: SearxngSearchResult[] = res.data.results;
|
const results: SearxngSearchResult[] = res.data.results;
|
||||||
const suggestions: string[] = res.data.suggestions;
|
const suggestions: string[] = res.data.suggestions;
|
||||||
|
|
||||||
return { results, suggestions };
|
// Create a URL for viewing the search results in the SearXNG web interface
|
||||||
|
const searchUrl = new URL(searxngURL);
|
||||||
|
searchUrl.pathname = '/search';
|
||||||
|
searchUrl.searchParams.append('q', query);
|
||||||
|
if (opts?.engines?.length) {
|
||||||
|
searchUrl.searchParams.append('engines', opts.engines.join(','));
|
||||||
|
}
|
||||||
|
if (opts?.language) {
|
||||||
|
searchUrl.searchParams.append('language', opts.language);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { results, suggestions, searchUrl: searchUrl.toString() };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue