-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathezil.js
115 lines (99 loc) · 2.87 KB
/
ezil.js
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
import * as p from "@clack/prompts";
import color from "picocolors";
import { openai } from "./openai.js";
import { webLoader, ytLoader } from "./utils/loader.js";
import { createVectorStore } from "./utils/store.js";
import { recursiveSplitter } from "./utils/docSplitter.js";
import { withLoading } from "./utils/loadingIndicator.js";
p.intro(`${color.bgWhite(color.black(" Ezil : CTRL + C to quit"))}`);
const getDataType = async () => {
return await p.select({
message: `Pick a data type : `,
initialValue: "youtube",
maxItems: 5,
options: [
{ value: "youtube", label: "Youtube" },
{ value: "web", label: "Web" },
],
});
};
const getUrl = async () => {
return await p.text({
placeholder: "http://..",
message: "Please enter Your URL",
validate: (value) => {
if (!value) return "Please enter a URL.";
},
});
};
const loadData = async (dataType, url) => {
let docs;
if (dataType === "youtube") {
docs = await ytLoader(url);
} else if (dataType === "web") {
docs = await webLoader(url);
}
return docs;
};
const splitAndIndex = async (docs) => {
const chunks = await recursiveSplitter(docs);
return await createVectorStore(chunks);
};
// QA
const askQuestions = async (store) => {
while (true) {
const query = await p.text({
message: color.green("Please enter your question: "),
validate: (value) => {
if (!value) return "Please enter your question.";
},
});
if (query.toLowerCase() === "exit") {
break;
}
const results = await withLoading(
() => store.similaritySearch(query, 2),
"Getting your answer."
);
const response = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
temperature: 0,
messages: [
{
role: "system",
content: "answer my question",
},
{
role: "user",
content: `
Context:${results.map((r) => r.pageContent).join("\n")}
Question:${query}
INSTRUCTIONS:
Answer the user's QUESTION using the Context text above.
Keep your answer grounded in the facts of the Context!
If the Context doesn’t contain the facts to answer the QUESTION, return "Oh, the documents aren’t sufficient!"
`,
},
],
});
p.outro(color.white(color.bold(response.choices[0].message.content)));
console.log([...new Set(results)].map((r) => r.metadata.source).join(","));
}
};
const main = async () => {
const dataType = await getDataType();
const url = await getUrl();
const docs = await withLoading(
() => loadData(dataType, url),
"Loading Your Data."
);
const store = await withLoading(
() => splitAndIndex(docs),
"Indexing and saving your data."
);
await askQuestions(store);
};
main().catch((error) => {
p.cancel(error.message);
process.exit(0);
});