adding clear methods for convos

This commit is contained in:
Daniel Avila 2023-02-06 21:17:46 -05:00
parent c7c50dbbab
commit 6e3f63ee46
16 changed files with 466 additions and 121 deletions

View file

@ -29,7 +29,7 @@ const titleConversation = async (message, response) => {
const openai = new OpenAIApi(configuration); const openai = new OpenAIApi(configuration);
const completion = await openai.createCompletion({ const completion = await openai.createCompletion({
model: 'text-davinci-002', model: 'text-davinci-002',
prompt: `Make a short title (goal: 5 words or less) in title case summarizing this conversation:\nuser:"${message}"\nGPT:"${response}"\nTitle: ` prompt: `Write a short title in title case, ideally in 5 words or less, and do not refer to the user or GPT, that summarizes this conversation:\nUser:"${message}"\nGPT:"${response}"\nTitle: `
}); });
console.log(completion.data.choices[0].text); console.log(completion.data.choices[0].text);
return completion.data.choices[0].text.replace(/\n/g, ''); return completion.data.choices[0].text.replace(/\n/g, '');

View file

@ -41,4 +41,5 @@ module.exports = {
}); });
}, },
getMessages: async (filter) => await Message.find(filter).exec(), getMessages: async (filter) => await Message.find(filter).exec(),
deleteMessages: async (filter) => await Message.deleteMany(filter).exec()
} }

257
package-lock.json generated
View file

@ -10,6 +10,7 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@keyv/mongo": "^2.1.8", "@keyv/mongo": "^2.1.8",
"@reduxjs/toolkit": "^1.9.2",
"chatgpt": "^4.1.1", "chatgpt": "^4.1.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
@ -20,6 +21,7 @@
"openai": "^3.1.0", "openai": "^3.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-textarea-autosize": "^8.4.0", "react-textarea-autosize": "^8.4.0",
"swr": "^2.0.3", "swr": "^2.0.3",
"url": "^0.11.0" "url": "^0.11.0"
@ -3591,6 +3593,29 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/@reduxjs/toolkit": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
"integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
"dependencies": {
"immer": "^9.0.16",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || ^18",
"react-redux": "^7.2.1 || ^8.0.2"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-redux": {
"optional": true
}
}
},
"node_modules/@types/body-parser": { "node_modules/@types/body-parser": {
"version": "1.19.2", "version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -3678,6 +3703,15 @@
"@types/range-parser": "*" "@types/range-parser": "*"
} }
}, },
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/html-minifier-terser": { "node_modules/@types/html-minifier-terser": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -3723,6 +3757,11 @@
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true "dev": true
}, },
"node_modules/@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"node_modules/@types/qs": { "node_modules/@types/qs": {
"version": "6.9.7", "version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@ -3735,12 +3774,27 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true "dev": true
}, },
"node_modules/@types/react": {
"version": "18.0.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/retry": { "node_modules/@types/retry": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true "dev": true
}, },
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"node_modules/@types/semver": { "node_modules/@types/semver": {
"version": "7.3.13", "version": "7.3.13",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
@ -3775,6 +3829,11 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"node_modules/@types/webidl-conversions": { "node_modules/@types/webidl-conversions": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@ -5696,6 +5755,11 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -7464,6 +7528,19 @@
"minimalistic-crypto-utils": "^1.0.1" "minimalistic-crypto-utils": "^1.0.1"
} }
}, },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoist-non-react-statics/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/hpack.js": { "node_modules/hpack.js": {
"version": "2.1.6", "version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@ -7717,6 +7794,15 @@
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true "dev": true
}, },
"node_modules/immer": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -10342,6 +10428,49 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
"integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
},
"peerDependencies": {
"@types/react": "^16.8 || ^17.0 || ^18.0",
"@types/react-dom": "^16.8 || ^17.0 || ^18.0",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0",
"react-native": ">=0.59",
"redux": "^4"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
},
"redux": {
"optional": true
}
}
},
"node_modules/react-textarea-autosize": { "node_modules/react-textarea-autosize": {
"version": "8.4.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz",
@ -10413,6 +10542,22 @@
"node": ">= 10.13.0" "node": ">= 10.13.0"
} }
}, },
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"peerDependencies": {
"redux": "^4"
}
},
"node_modules/regenerate": { "node_modules/regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -10556,6 +10701,11 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true "dev": true
}, },
"node_modules/reselect": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.1", "version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@ -14826,6 +14976,17 @@
"fastq": "^1.6.0" "fastq": "^1.6.0"
} }
}, },
"@reduxjs/toolkit": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.2.tgz",
"integrity": "sha512-5ZAZ7hwAKWSii5T6NTPmgIBUqyVdlDs+6JjThz6J6dmHLDm6zCzv2OjHIFAi3Vvs1qjmXU0bm6eBojukYXjVMQ==",
"requires": {
"immer": "^9.0.16",
"redux": "^4.2.0",
"redux-thunk": "^2.4.2",
"reselect": "^4.1.7"
}
},
"@types/body-parser": { "@types/body-parser": {
"version": "1.19.2", "version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -14913,6 +15074,15 @@
"@types/range-parser": "*" "@types/range-parser": "*"
} }
}, },
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": { "@types/html-minifier-terser": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -14958,6 +15128,11 @@
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true "dev": true
}, },
"@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"@types/qs": { "@types/qs": {
"version": "6.9.7", "version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
@ -14970,12 +15145,27 @@
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true "dev": true
}, },
"@types/react": {
"version": "18.0.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"@types/retry": { "@types/retry": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
"integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
"dev": true "dev": true
}, },
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"@types/semver": { "@types/semver": {
"version": "7.3.13", "version": "7.3.13",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
@ -15010,6 +15200,11 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
},
"@types/webidl-conversions": { "@types/webidl-conversions": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@ -16509,6 +16704,11 @@
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
"dev": true "dev": true
}, },
"csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -17847,6 +18047,21 @@
"minimalistic-crypto-utils": "^1.0.1" "minimalistic-crypto-utils": "^1.0.1"
} }
}, },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
},
"dependencies": {
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
}
},
"hpack.js": { "hpack.js": {
"version": "2.1.6", "version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@ -18033,6 +18248,11 @@
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"dev": true "dev": true
}, },
"immer": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.19.tgz",
"integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ=="
},
"import-fresh": { "import-fresh": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@ -19782,6 +20002,24 @@
"scheduler": "^0.23.0" "scheduler": "^0.23.0"
} }
}, },
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"react-redux": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz",
"integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==",
"requires": {
"@babel/runtime": "^7.12.1",
"@types/hoist-non-react-statics": "^3.3.1",
"@types/use-sync-external-store": "^0.0.3",
"hoist-non-react-statics": "^3.3.2",
"react-is": "^18.0.0",
"use-sync-external-store": "^1.0.0"
}
},
"react-textarea-autosize": { "react-textarea-autosize": {
"version": "8.4.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.0.tgz",
@ -19837,6 +20075,20 @@
"resolve": "^1.20.0" "resolve": "^1.20.0"
} }
}, },
"redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"redux-thunk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz",
"integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==",
"requires": {}
},
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@ -19952,6 +20204,11 @@
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true "dev": true
}, },
"reselect": {
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
"integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A=="
},
"resolve": { "resolve": {
"version": "1.22.1", "version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",

View file

@ -22,6 +22,7 @@
"homepage": "https://github.com/danny-avila/rpp2210-mvp#readme", "homepage": "https://github.com/danny-avila/rpp2210-mvp#readme",
"dependencies": { "dependencies": {
"@keyv/mongo": "^2.1.8", "@keyv/mongo": "^2.1.8",
"@reduxjs/toolkit": "^1.9.2",
"chatgpt": "^4.1.1", "chatgpt": "^4.1.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
@ -32,6 +33,7 @@
"openai": "^3.1.0", "openai": "^3.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-textarea-autosize": "^8.4.0", "react-textarea-autosize": "^8.4.0",
"swr": "^2.0.3", "swr": "^2.0.3",
"url": "^0.11.0" "url": "^0.11.0"

View file

@ -1,7 +1,7 @@
const express = require('express'); const express = require('express');
const dbConnect = require('../models/dbConnect'); const dbConnect = require('../models/dbConnect');
const { ask, titleConversation } = require('../app/chatgpt'); const { ask, titleConversation } = require('../app/chatgpt');
const { saveMessage, getMessages } = require('../models/Message'); const { saveMessage, getMessages, deleteAllMessages } = require('../models/Message');
const { saveConversation, getConversations } = require('../models/Conversation'); const { saveConversation, getConversations } = require('../models/Conversation');
const crypto = require('crypto'); const crypto = require('crypto');
const path = require('path'); const path = require('path');
@ -30,6 +30,13 @@ app.get('/messages/:conversationId', async (req, res) => {
res.status(200).send(await getMessages({ conversationId })); res.status(200).send(await getMessages({ conversationId }));
}); });
app.post('/clear_convos', async (req, res) => {
const { conversationId } = req.body;
console.log('conversationId', conversationId);
const filter = {};
res.status(201).send(await deleteAllMessages(filter));
});
app.post('/ask', async (req, res) => { app.post('/ask', async (req, res) => {
console.log(req.body); console.log(req.body);
const { text, parentMessageId, conversationId } = req.body; const { text, parentMessageId, conversationId } = req.body;

View file

@ -9,13 +9,14 @@ import useDidMountEffect from './hooks/useDidMountEffect.js';
import axios from 'axios'; import axios from 'axios';
const fetcher = (url) => fetch(url).then((res) => res.json()); const fetcher = (url) => fetch(url).then((res) => res.json());
const postRequest = async (url, { arg }) => await axios.post(url, { arg });
const App = () => { const App = () => {
const [messages, setMessages] = useState([]); const [messages, setMessages] = useState([]);
const [convo, setConvo] = useState({ conversationId: null, parentMessageId: null }); const [convo, setConvo] = useState({ conversationId: null, parentMessageId: null });
const { data, error, isLoading, mutate } = useSWR('http://localhost:3050/convos', fetcher); const { data, error, isLoading, mutate } = useSWR('http://localhost:3050/convos', fetcher);
const { trigger, isMutating } = useSWRMutation( const conversation = useSWRMutation( //{ trigger, isMutating }
`http://localhost:3050/messages/${convo.conversationId}`, `http://localhost:3050/messages/${convo.conversationId}`,
fetcher, fetcher,
{ {
@ -26,7 +27,7 @@ const App = () => {
} }
); );
useDidMountEffect(() => trigger(), [convo]); useDidMountEffect(() => conversation.trigger(), [convo]);
const onConvoClick = (conversationId, parentMessageId) => { const onConvoClick = (conversationId, parentMessageId) => {
console.log('convo was clicked'); console.log('convo was clicked');
@ -38,6 +39,7 @@ const App = () => {
{/* <div className="w-80 bg-slate-800"></div> */} {/* <div className="w-80 bg-slate-800"></div> */}
<Nav <Nav
conversations={data} conversations={data}
convo={convo}
convoHandler={onConvoClick} convoHandler={onConvoClick}
/> />
{/* <div className="flex h-full flex-1 flex-col md:pl-[260px]"> */} {/* <div className="flex h-full flex-1 flex-col md:pl-[260px]"> */}

View file

@ -1,8 +1,11 @@
import React from 'react'; import React from 'react';
import RenameButton from './RenameButton';
import DeleteButton from './DeleteButton';
export default function Conversation({ export default function Conversation({
id, id,
parentMessageId, parentMessageId,
convo,
convoHandler, convoHandler,
title = 'New conversation' title = 'New conversation'
}) { }) {
@ -29,52 +32,8 @@ export default function Conversation({
{title} {title}
</div> </div>
<div className="visible absolute right-1 z-10 flex text-gray-300"> <div className="visible absolute right-1 z-10 flex text-gray-300">
<button className="p-1 hover:text-white"> <RenameButton />
<svg <DeleteButton />
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M12 20h9" />
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
</svg>
</button>
<button className="p-1 hover:text-white">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<polyline points="3 6 5 6 21 6"></polyline>
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
<line
x1="10"
y1="11"
x2="10"
y2="17"
/>
<line
x1="14"
y1="11"
x2="14"
y2="17"
/>
</svg>
</button>
</div> </div>
</a> </a>
); );

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import Conversation from './Conversation'; import Conversation from './Conversation';
export default function Conversations({ conversations, convoHandler }) { export default function Conversations({ convoState, conversations, convoHandler }) {
return ( return (
<div className="-mr-2 flex-1 flex-col overflow-y-auto border-b border-white/20"> <div className="-mr-2 flex-1 flex-col overflow-y-auto border-b border-white/20">
<div className="flex flex-col gap-2 text-sm text-gray-100"> <div className="flex flex-col gap-2 text-sm text-gray-100">
@ -12,6 +12,7 @@ export default function Conversations({ conversations, convoHandler }) {
id={convo.conversationId} id={convo.conversationId}
parentMessageId={convo.parentMessageId} parentMessageId={convo.parentMessageId}
title={convo.title} title={convo.title}
convo={convoState}
convoHandler={convoHandler} convoHandler={convoHandler}
/> />
))} ))}

View file

@ -0,0 +1,35 @@
import React from 'react';
export default function DeleteButton({ onClick, disabled }) {
return (
<button className="p-1 hover:text-white">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<polyline points="3 6 5 6 21 6" />
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
<line
x1="10"
y1="11"
x2="10"
y2="17"
/>
<line
x1="14"
y1="11"
x2="14"
y2="17"
/>
</svg>
</button>
);
}

View file

@ -3,14 +3,14 @@ import NewChat from './NewChat';
import Conversations from './Conversations'; import Conversations from './Conversations';
import NavLinks from './NavLinks'; import NavLinks from './NavLinks';
export default function Nav({ conversations, convoHandler }) { export default function Nav({ conversations, convo, convoHandler }) {
return ( return (
<div className="dark hidden bg-gray-900 md:fixed md:inset-y-0 md:flex md:w-[260px] md:flex-col"> <div className="dark hidden bg-gray-900 md:fixed md:inset-y-0 md:flex md:w-[260px] md:flex-col">
<div className="flex h-full min-h-0 flex-col "> <div className="flex h-full min-h-0 flex-col ">
<div className="scrollbar-trigger flex h-full w-full flex-1 items-start border-white/20"> <div className="scrollbar-trigger flex h-full w-full flex-1 items-start border-white/20">
<nav className="flex h-full flex-1 flex-col space-y-1 p-2"> <nav className="flex h-full flex-1 flex-col space-y-1 p-2">
<NewChat /> <NewChat />
<Conversations conversations={conversations} convoHandler={convoHandler}/> <Conversations convoState={convo} conversations={conversations} convoHandler={convoHandler}/>
<NavLinks /> <NavLinks />
</nav> </nav>
</div> </div>

View file

@ -0,0 +1,23 @@
import React from 'react';
export default function RenameButton({ onClick, disabled }) {
return (
<button className="p-1 hover:text-white">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="h-4 w-4"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M12 20h9" />
<path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
</svg>
</button>
);
}

View file

@ -0,0 +1,28 @@
import React from 'react';
export default function SubmitButton({ onClick, disabled }) {
return (
<button onClick={onClick} className="absolute bottom-1.5 right-1 rounded-md p-1 text-gray-500 hover:bg-gray-100 disabled:hover:bg-transparent dark:hover:bg-gray-900 dark:hover:text-gray-400 dark:disabled:hover:bg-transparent md:bottom-2.5 md:right-2">
<svg
stroke="currentColor"
fill="none"
strokeWidth="2"
viewBox="0 0 24 24"
strokeLinecap="round"
strokeLinejoin="round"
className="mr-1 h-4 w-4"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<line
x1="22"
y1="2"
x2="11"
y2="13"
/>
<polygon points="22 2 15 22 11 13 2 9 22 2" />
</svg>
</button>
);
}

View file

@ -1,64 +1,11 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { SSE } from '../../app/sse'; import SubmitButton from './SubmitButton';
import TextareaAutosize from 'react-textarea-autosize'; import TextareaAutosize from 'react-textarea-autosize';
import handleSubmit from '../utils/handleSubmit';
const handleSubmit = (text, messageHandler, convo, convoHandler) => { export default function TextChat({ messages, setMessages, reloadConvos, convo, setConvo }) {
let payload = { text };
if (convo.conversationId && convo.parentMessageId) {
payload = {
...payload,
conversationId: convo.conversationId,
parentMessageId: convo.parentMessageId
};
}
const events = new SSE('http://localhost:3050/ask', {
payload: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' }
});
events.onopen = function () {
console.log('connection is opened');
};
events.onmessage = function (e) {
const data = JSON.parse(e.data);
if (!!data.message) {
messageHandler(data.text.replace(/^\n/, ''));
} else {
console.log(data);
convoHandler(data);
}
};
events.onerror = function (e) {
console.log(e, 'error in opening conn.');
events.close();
};
events.stream();
};
export default function TextChat({
messages,
setMessages,
reloadConvos,
convo,
setConvo,
}) {
const [text, setText] = useState(''); const [text, setText] = useState('');
// const [convo, setConvo] = useState({ conversationId: null, parentMessageId: null }); const submitMessage = () => {
// if (!!conversation) {
// setConvo(conversation);
// }
const handleKeyPress = (e) => {
if (e.key === 'Enter' && e.shiftKey) {
console.log('Enter + Shift');
}
if (e.key === 'Enter' && !e.shiftKey) {
const payload = text.trim(); const payload = text.trim();
const currentMsg = { sender: 'user', text: payload, current: true }; const currentMsg = { sender: 'user', text: payload, current: true };
setMessages([...messages, currentMsg]); setMessages([...messages, currentMsg]);
@ -76,6 +23,15 @@ export default function TextChat({
}; };
console.log('User Input:', payload); console.log('User Input:', payload);
handleSubmit(payload, messageHandler, convo, convoHandler); handleSubmit(payload, messageHandler, convo, convoHandler);
};
const handleKeyPress = (e) => {
if (e.key === 'Enter' && e.shiftKey) {
console.log('Enter + Shift');
}
if (e.key === 'Enter' && !e.shiftKey) {
submitMessage();
} }
}; };
@ -103,7 +59,8 @@ export default function TextChat({
placeholder="" placeholder=""
className="m-0 h-auto max-h-52 resize-none overflow-auto border-0 bg-transparent p-0 pl-2 pr-7 leading-6 focus:outline-none focus:ring-0 focus-visible:ring-0 dark:bg-transparent md:pl-0" className="m-0 h-auto max-h-52 resize-none overflow-auto border-0 bg-transparent p-0 pl-2 pr-7 leading-6 focus:outline-none focus:ring-0 focus-visible:ring-0 dark:bg-transparent md:pl-0"
/> />
<button className="absolute bottom-1.5 right-1 rounded-md p-1 text-gray-500 hover:bg-gray-100 disabled:hover:bg-transparent dark:hover:bg-gray-900 dark:hover:text-gray-400 dark:disabled:hover:bg-transparent md:bottom-2.5 md:right-2"> <SubmitButton onClick={() => submitMessage()} />
{/* <button className="absolute bottom-1.5 right-1 rounded-md p-1 text-gray-500 hover:bg-gray-100 disabled:hover:bg-transparent dark:hover:bg-gray-900 dark:hover:text-gray-400 dark:disabled:hover:bg-transparent md:bottom-2.5 md:right-2">
<svg <svg
stroke="currentColor" stroke="currentColor"
fill="none" fill="none"
@ -124,7 +81,7 @@ export default function TextChat({
/> />
<polygon points="22 2 15 22 11 13 2 9 22 2" /> <polygon points="22 2 15 22 11 13 2 9 22 2" />
</svg> </svg>
</button> </button> */}
</div> </div>
</div> </div>
</form> </form>

40
src/utils/handleSubmit.js Normal file
View file

@ -0,0 +1,40 @@
import { SSE } from '../../app/sse';
export default function handleSubmit(text, messageHandler, convo, convoHandler) {
let payload = { text };
if (convo.conversationId && convo.parentMessageId) {
payload = {
...payload,
conversationId: convo.conversationId,
parentMessageId: convo.parentMessageId
};
}
const events = new SSE('http://localhost:3050/ask', {
payload: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' }
});
events.onopen = function () {
console.log('connection is opened');
};
events.onmessage = function (e) {
const data = JSON.parse(e.data);
if (!!data.message) {
messageHandler(data.text.replace(/^\n/, ''));
} else if (!data.initial) {
console.log(data);
convoHandler(data);
} else {
console.log('initial', data);
}
};
events.onerror = function (e) {
console.log(e, 'error in opening conn.');
events.close();
};
events.stream();
};

22
store/convoSlice.js Normal file
View file

@ -0,0 +1,22 @@
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
active: false,
conversationId: null,
parentMessageId: null,
};
const currentSlice = createSlice({
name: 'convo',
initialState,
reducers: {
setConversation: (state, action) => {
const { payload } = action;
state = { ...state, ...payload };
},
}
});
export const { setConversation } = currentSlice.actions;
export default currentSlice.reducer;

11
store/index.js Normal file
View file

@ -0,0 +1,11 @@
import { configureStore } from '@reduxjs/toolkit';
import convoReducer from './convoSlice.js';
// import uploadReducer from './uploadSlice.js';
export const store = configureStore({
reducer: {
convo: convoReducer,
// upload: uploadReducer,
},
});