-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgraphql-assistant-agent.js
134 lines (119 loc) · 4.99 KB
/
graphql-assistant-agent.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
const {promisify} = require('util');
const fs = require('fs');
const csv = require('csv-parser');
const makersApi = require('./makers-api');
const vectorDbApi = require("./vector-db-api");
const inputFile = 'assets/pre-process.csv';
const outputFile = 'assets/post-process.csv';
const writeFileAsync = promisify(fs.writeFile);
function getSearchGraphQLPrompt(text, similarQueries) {
let similarQueriesText = ""
if (similarQueriesText.length > 0) {
similarQueriesText = 'For contextual understanding, consider the following known queries that have similar purpose: \n'
}
similarQueries.forEach((query, index) => {
similarQueriesText += `#### Set ${index + 1}:\n` + `Query: '''\n${query.query}'''\n`
});
return 'Your task: Given the user\'s free-text sentence below, convert it into a valid GraphQL query using the monday.com API. ' +
'Incorporate any specific parameters like \'board IDs\',\'column ids\', \'column values\', etc., mentioned in the user\'s description into the resulting GraphQL query. Output the query only, nothing else.\n'
+ '\n' + 'User\'s Query Description:\n' + `'''${text}'''` + '\n' + `${similarQueriesText}` + '\n' + 'REMEMBER, to return only a GraphQL valid query.\n' + '\n' + 'Your GraphQL query:';
}
async function getGraphQLQuery(text, shouldUseSimilarQueries) {
let similarQueries = []
if (shouldUseSimilarQueries) {
const response = await vectorDbApi.queryVectors(text, 6);
similarQueries = response.matches.map((vector) => {
return {
query: vector.metadata.query, description: vector.metadata.description,
}
});
}
const prompt = getSearchGraphQLPrompt(text, similarQueries);
console.log("Prompt is:", prompt)
const result = await makersApi.prompt(prompt, {temperature: 0.1});
console.log("Result is:", JSON.stringify(result));
if (result && result[0].candidates) {
return {
query: cleanFormattingCharacters(result[0].candidates[0].output)
}
} else {
return {
query: ""
}
}
}
function cleanFormattingCharacters(string) {
return string.replace(/\s+/g, ' ');
}
function createPromptGraphQLDescription(query) {
return 'You\'re an expert in GraphQL and intimately familiar with the monday.com API. \n' +
'I have a GraphQL query from the monday.com API that I\'d like you to explain. \n' +
'Please cover the query\'s purpose, the arguments it accepts, and the output it generates.\n' +
'\n' + 'Here is the GraphQL query:\n' +
'\n' + '```graphql\n' +
`${query}\n`;
}
// Function to sanitize the description for CSV
function sanitizeForCSV(description) {
// Escape double quotes and enclose in double quotes
return `"${description.replace(/"/g, '""')}"`;
}
async function generateDescription() {
const rows = await readCSV(inputFile);
const outputData = [];
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const query = row.query;
try {
console.log(`Processing row ${i + 1} out of ${rows.length}`);
const prompt = createPromptGraphQLDescription(query);
const result = await makersApi.prompt(prompt);
const candidates = result[0].candidates;
const sanitizedDesc = sanitizeForCSV(candidates[0].output);
const sanitizedQuery = sanitizeForCSV(row.query);
outputData.push({description: sanitizedDesc, query: sanitizedQuery});
} catch (error) {
console.error(`Error processing row with query: ${query}`, '\n', error);
}
}
// Write the processed data to the output CSV file
const csvData = outputData.map((row) => `${row.description},${row.query}`).join('\n');
try {
await writeFileAsync(outputFile, csvData);
console.log('Output file has been written successfully.');
} catch (error) {
console.error('Error writing to output file:', error);
}
}
async function readCSV(filePath) {
return new Promise((resolve, reject) => {
const rows = [];
fs.createReadStream(filePath).pipe(csv()).on('data', (row) => {
rows.push(row);
}).on('end', () => {
resolve(rows);
}).on('error', (error) => {
reject(error);
});
});
}
async function fillIndexWithVectors() {
const rows = await readCSV(outputFile)
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const item = {
id: i, description: row.description, query: row.query
}
try {
console.log(`Processing row ${i + 1} out of ${rows.length}`);
const index = await vectorDbApi.addVectors([item]);
console.log(`Vector added to DB for row ${i + 1}`)
} catch (error) {
console.error(`Error processing row with values: ${item}`, '\n', error);
}
}
return 'Success';
}
module.exports = {
generateDescription, fillIndexWithVectors, getGraphQLQuery
};