Spaces:
Build error
Build error
File size: 4,340 Bytes
0c4cf03 6434339 0c4cf03 6434339 0c4cf03 6f7b315 0c4cf03 0aa57de 0c4cf03 0aa57de 6434339 0c4cf03 6434339 0c4cf03 6434339 0c4cf03 6434339 0c4cf03 6f7b315 0c4cf03 6434339 0c4cf03 0aa57de 0c4cf03 6434339 0c4cf03 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import { authCondition } from "$lib/server/auth";
import { collections } from "$lib/server/database";
import { defaultModel } from "$lib/server/models";
import { searchWeb } from "$lib/server/websearch/searchWeb";
import type { Message } from "$lib/types/Message";
import { error } from "@sveltejs/kit";
import { ObjectId } from "mongodb";
import { z } from "zod";
import type { WebSearch } from "$lib/types/WebSearch";
import { generateQuery } from "$lib/server/websearch/generateQuery";
import { parseWeb } from "$lib/server/websearch/parseWeb";
import { summarizeWeb } from "$lib/server/websearch/summarizeWeb";
interface GenericObject {
[key: string]: GenericObject | unknown;
}
function removeLinks(obj: GenericObject) {
for (const prop in obj) {
if (prop.endsWith("link")) delete obj[prop];
else if (typeof obj[prop] === "object") removeLinks(obj[prop] as GenericObject);
}
return obj;
}
export async function GET({ params, locals, url }) {
const model = defaultModel;
const convId = new ObjectId(params.id);
const searchId = new ObjectId();
const conv = await collections.conversations.findOne({
_id: convId,
...authCondition(locals),
});
if (!conv) {
throw error(404, "Conversation not found");
}
const prompt = z.string().trim().min(1).parse(url.searchParams.get("prompt"));
const messages = (() => {
return [...conv.messages, { content: prompt, from: "user", id: crypto.randomUUID() }];
})() satisfies Message[];
const stream = new ReadableStream({
async start(controller) {
const webSearch: WebSearch = {
_id: searchId,
convId: convId,
prompt: prompt,
searchQuery: "",
knowledgeGraph: "",
answerBox: "",
results: [],
summary: "",
messages: [],
createdAt: new Date(),
updatedAt: new Date(),
};
function appendUpdate(message: string, args?: string[], type?: "error" | "update") {
webSearch.messages.push({
type: type ?? "update",
message,
args,
});
controller.enqueue(JSON.stringify({ messages: webSearch.messages }));
}
try {
appendUpdate("Generating search query");
webSearch.searchQuery = await generateQuery(messages, model);
appendUpdate("Searching Google", [webSearch.searchQuery]);
const results = await searchWeb(webSearch.searchQuery);
let text = "";
webSearch.results =
(results.organic_results &&
results.organic_results.map((el: { link: string }) => el.link)) ??
[];
if (results.answer_box) {
// if google returns an answer box, we use it
webSearch.answerBox = JSON.stringify(removeLinks(results.answer_box));
text = webSearch.answerBox;
appendUpdate("Found a Google answer box");
} else if (results.knowledge_graph) {
// if google returns a knowledge graph, we use it
webSearch.knowledgeGraph = JSON.stringify(removeLinks(results.knowledge_graph));
text = webSearch.knowledgeGraph;
appendUpdate("Found a Google knowledge page");
} else if (webSearch.results.length > 0) {
let tries = 0;
while (!text && tries < 3) {
const searchUrl = webSearch.results[tries];
appendUpdate("Browsing result", [JSON.stringify(searchUrl)]);
try {
text = await parseWeb(searchUrl);
if (!text) throw new Error("text of the webpage is null");
} catch (e) {
appendUpdate("Error parsing webpage", [], "error");
tries++;
}
}
if (!text) throw new Error("No text found on the first 3 results");
} else {
throw new Error("No results found for this search query");
}
appendUpdate("Creating summary");
webSearch.summary = await summarizeWeb(text, webSearch.searchQuery, model);
appendUpdate("Injecting summary", [JSON.stringify(webSearch.summary)]);
} catch (searchError) {
if (searchError instanceof Error) {
webSearch.messages.push({
type: "error",
message: "An error occurred with the web search",
args: [JSON.stringify(searchError.message)],
});
}
}
const res = await collections.webSearches.insertOne(webSearch);
webSearch.messages.push({
type: "result",
id: res.insertedId.toString(),
});
controller.enqueue(JSON.stringify({ messages: webSearch.messages }));
},
});
return new Response(stream, { headers: { "Content-Type": "application/json" } });
}
|