-
Notifications
You must be signed in to change notification settings - Fork 0
/
chat3.js
256 lines (214 loc) · 8.62 KB
/
chat3.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
import pkg from "whatsapp-web.js";
import qrcode from "qrcode-terminal";
import puppeteer from "puppeteer";
import dotenv from "dotenv";
import fs from "fs";
import { GoogleGenerativeAI } from "@google/generative-ai";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { ChatVertexAI, VertexAI } from "@langchain/google-vertexai";
import { Document } from "langchain/document";
import { GoogleGenerativeAIEmbeddings } from "@langchain/google-genai";
import { TaskType } from "@google/generative-ai";
import { createRetrievalChain } from "langchain/chains/retrieval";
//import { GoogleAuth } from '@google-cloud/auth';
// const auth = await GoogleAuth.default();
// const credentials = await auth.getClientCredentials();
// Load environment variables from .env file
dotenv.config();
// Load the service account key file
const keyPath = 'key.json';
const key = fs.readFileSync(keyPath);
process.env.GOOGLE_APPLICATION_CREDENTIALS = keyPath;
const { Client, LocalAuth } = pkg;
// const model = new ChatVertexAI({
// model: "gemini-1.5-flash",
// temperature: 0,
// });
const model = new ChatVertexAI({
model: "gemini-1.5-flash",
temperature: 0,
});
const textSplitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
});
// Read the content of synthetic_data.txt
const syntheticData = fs.readFileSync("synthetic_data.txt", "utf-8");
// Split the synthetic data into manageable chunks
const docs = new Document({ content: syntheticData,metadata: {} });
//const splits = await textSplitter.splitDocuments(docs);
const embeddings = new GoogleGenerativeAIEmbeddings({
model: "text-embedding-004", // 768 dimensions
taskType: TaskType.RETRIEVAL_DOCUMENT,
title: "Document title",
apiKey: process.env.API_KEY,
});
const vectorstore = await MemoryVectorStore.fromDocuments(
[docs],
embeddings
);
const retriever = vectorstore.asRetriever();
// Error handling function (optional)
function handleError(err) {
console.error("Error:", err);
// Add more robust error handling here (e.g., retry logic, user notifications)
}
const systemTemplate = [
`##Tentang
Kamu adalah customer service sebuah program beasiswa dari Stargan Mitra Teknologi bernama program Stargan Bisnis Digital, Inovasi, dan Kewirausahaan dengan nama Rai.
##Tugas
Tugas kamu adalah menjawab pertanyaan terkait mata kuliah. Kamu hanya menjawab dalam maksimum 1 paragraf saja dengan bahasa Indonesia yang sopan dan ramah tanpa emoticon.
##Panggilan
Selalu panggil dengan "Kak" atau "Kakak" atau "Juragan" atau "Agan" dan hindari memanggil dengan sebutan "Anda".
##Batasan
Jawab hanya yang kamu tahu saja. Arahkan mereka untuk kontak ke [email protected] jika terdapat kendala.
##Rekomendasi
Kamu juga dapat memberikan rekomendasi mata kuliah dari data yang kamu punya jika mereka menanyakan rekomendasi yang diambil.
Tanyakan dulu mengenai kenginan profesi dia, dan atau jumlah maksimal mata kuliah yang bisa diambil.
Kemudian cocokkan dengan data yang kamu punya. Rekomendasikan setidaknya 5 mata kuliah.
##Call to Action
Arahkan untuk segera mendaftar ke program Stargan Bisnis Digital, Inovasi, dan Kewirausahaan di starganteknologi.com dan hubungi [email protected] jika terdapat kendala.
`,
`\n\n`,
`{context}`,
].join("");
// Function to load synthetic data
function loadSyntheticData() {
try {
return fs.readFileSync("synthetic_data.txt", "utf-8");
} catch (error) {
handleError(error);
return ""; // Handle empty data gracefully
}
}
const prompt = ChatPromptTemplate.fromMessages([
["system", systemTemplate],
["human", "{input}"],
]);
// Function to initialize the generative AI model
function initializeGenerativeAI() {
return new GoogleGenerativeAI({
credentials: process.env.GOOGLE_APPLICATION_CREDENTIALS, // Use environment variable for credentials
model: "gemini-1.5-flash",
temperature: 0, // Optionally adjust the temperature
});
}
// Function to create a chat session
// Function to handle chat response
async function handleChat(model, inputMessage) {
try {
// 1. Combine user message with system template for context:
const contextMessage = systemTemplate.replace("{context}", inputMessage);
// 2. Use Langchain retrieval chain to find relevant data:
const relevantData = await ragChain.invoke({ input: contextMessage });
// 3. Generate response using the model:
let responseText;
if (relevantData) {
// Use relevant data to inform the response generation
responseText = await model.ChatPromptTemplate({
prompt: inputMessage + "\n" + relevantData, // Combine user message and retrieved data
maxOutputTokens: 200,
});
} else {
// Fallback to model-only response if no relevant data found
responseText = await model.ChatPromptTemplate({
prompt: inputMessage,
maxOutputTokens: 200,
});
}
return responseText.text; // Return the model's text response
} catch (error) {
console.error("Error in chat handling:", error);
return "Sorry, there was an issue processing your request.";
}
}
const questionAnswerChain = await createStuffDocumentsChain({
llm: model,
prompt,
});
const ragChain = await createRetrievalChain({
retriever,
combineDocsChain: questionAnswerChain,
});
// Function to embed synthetic data and store it in a vector store
// Function to find the most relevant response from synthetic data using embeddings
async function getRelevantData(query, vectorStore) {
const results = await vectorStore.similaritySearch(query, 1);
return results[0]?.pageContent || ""; // Return the most relevant content
}
async function main() {
const syntheticData = loadSyntheticData();
const model = initializeGenerativeAI();
// Embed the synthetic data to create a vector store
const client = new Client({
authStrategy: new LocalAuth(), // Automatically saves the session in .wwebjs_auth/
puppeteer: {
executablePath: puppeteer.executablePath(), // Use Puppeteer installed in your project
headless: true, // Run browser in headless mode
args: ["--no-sandbox", "--disable-setuid-sandbox"], // For environments with limited sandboxing support
},
});
// Listen for QR code generation and display it in the terminal
client.on("qr", (qr) => {
console.log("Scan this QR code with your WhatsApp to log in:");
qrcode.generate(qr, { small: true });
});
// Log a message when authenticated
client.on("authenticated", () => {
console.log("WhatsApp client authenticated!");
});
// Handle client ready state
client.on("ready", () => {
console.log("WhatsApp client is ready to send and receive messages!");
});
// Handle incoming messages
client.on("message", async (msg) => {
console.log(`Received message from ${msg.from}: ${msg.body}`);
const handleUserMessage = async (message) => {
if (message === "!ping") {
return "pong";
} else if (message.startsWith("!echo ")) {
return message.slice(6); // Extract the text after "!echo "
} else if (message === "!mediainfo" && msg.hasMedia) {
const attachmentData = await msg.downloadMedia();
return `
*Media Info*
MimeType: ${attachmentData.mimetype}
Filename: ${attachmentData.filename || "unknown"}
Data Size: ${attachmentData.data.length} bytes
`;
} else {
// const results = await ragChain.invoke({
// input: "What are you?",
// });
// return results;
// Get response from the model
const response = await handleChat(model, message);
//console.log(response);
return response;
}
};
const replyText = await handleUserMessage(msg.body);
if (replyText) {
await msg.reply(replyText);
}
});
// Handle authentication failures
client.on("auth_failure", handleError);
// Handle client disconnection
client.on("disconnected", (reason) => {
console.log("WhatsApp client disconnected:", reason);
process.exit(); // Exit the process to restart the client
});
async function sendMessageToChatbot(message) {
const context = new Document({ content: message });
const response = await chat.sendMessage(message, { context });
return response.text;
}
// Initialize the WhatsApp client
client.initialize();
}
main();