From 303a43d54a6e9e85bb4784b963fd9ba19194e1dc Mon Sep 17 00:00:00 2001 From: Igor Ramadas Date: Tue, 7 Nov 2023 23:52:14 +0100 Subject: [PATCH] Custom ChatGPT prompts enabled in beta. --- pages/account/index.vue | 13 ++++++++++++- src/routes/api/users.ts | 25 +++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/pages/account/index.vue b/pages/account/index.vue index f7d2efbc..343abef7 100644 --- a/pages/account/index.vue +++ b/pages/account/index.vue @@ -81,7 +81,7 @@
-

{{ user.isPro ? "FTP auto update" : "FTP auto update (PRO only)" }}

+

FTP auto update{{ user.isPro ? "" : " (PRO only)" }}

Strautomator can automatically update your cycling FTP and your estimated fitness level based on your recent activities.
@@ -158,6 +158,14 @@ +
+

ChatGPT custom prompt{{ user.isPro ? "" : " (PRO only)" }}

+
+ You can enhance the generated activity names with ChatGPT by using your own custom prompt, that will be appended to the default one. + More details... +
+ +

Status: {{ $store.state.user.isPro ? "PRO" : "Free" }} account

@@ -365,6 +373,7 @@ export default { const noSuffixes = preferences.noSuffixes || false const ftpAutoUpdate = preferences.ftpAutoUpdate || false const language = preferences.language || "en" + const chatGptPrompt = preferences.chatGptPrompt || "" const weatherProvider = user.isPro ? preferences.weatherProvider || null : null const weatherUnit = preferences.weatherUnit || "c" const windSpeedUnit = preferences.windSpeedUnit ? preferences.windSpeedUnit : weatherUnit == "f" ? "mph" : "kph" @@ -420,6 +429,7 @@ export default { minDateReset: this.$dayjs().format(dateFormat), maxDateReset: this.$dayjs().add(1, "year").format(dateFormat), language: language, + chatGptPrompt: chatGptPrompt, weatherProvider: weatherProvider, weatherUnit: weatherUnit, windSpeedUnit: windSpeedUnit, @@ -623,6 +633,7 @@ export default { weatherUnit: this.weatherUnit, windSpeedUnit: this.windSpeedUnit, language: this.language, + chatGptPrompt: this.chatGptPrompt, dateResetCounter: this.resetCounter ? arrDate.join("-") : false } diff --git a/src/routes/api/users.ts b/src/routes/api/users.ts index 47b1da11..520e30f6 100644 --- a/src/routes/api/users.ts +++ b/src/routes/api/users.ts @@ -1,6 +1,6 @@ // Strautomator API: Users -import {logHelper, gdpr, recipes, subscriptions, strava, users, RecipeData, RecipeStatsData, UserData, UserPreferences} from "strautomator-core" +import {logHelper, gdpr, openai, recipes, subscriptions, strava, users, RecipeData, RecipeStatsData, UserData, UserPreferences} from "strautomator-core" import auth from "../auth" import dayjs from "../../dayjs" import _ from "lodash" @@ -149,16 +149,16 @@ router.post("/:userId/preferences", async (req: express.Request, res: express.Re preferences.weatherProvider = req.body.weatherProvider } - // Make sure linksOn is valid. - if (preferenceChanged("linksOn")) { - preferences.linksOn = req.body.linksOn - } - // Make sure ftpAutoUpdate is valid. if (preferenceChanged("ftpAutoUpdate") && user.isPro) { preferences.ftpAutoUpdate = req.body.ftpAutoUpdate ? true : false } + // Make sure linksOn is valid. + if (preferenceChanged("linksOn")) { + preferences.linksOn = req.body.linksOn + } + // Make sure weather unit is valid. if (preferenceChanged("weatherUnit")) { preferences.weatherUnit = req.body.weatherUnit != "c" ? "f" : "c" @@ -214,6 +214,19 @@ router.post("/:userId/preferences", async (req: express.Request, res: express.Re } } + // Set the ChatGPT custom prompt? Make sure it ends with a period and passes the OpenAI moderation. + if (preferenceChanged("chatGptPrompt") && user.isPro && user.isBeta) { + const lastChar = req.body.chatGptPrompt.substring(req.body.chatGptPrompt.length - 1) + if (![".", "!", "?"].includes(lastChar)) { + req.body.chatGptPrompt += "." + } + const failedCategories = await openai.validatePrompt(user, req.body.chatGptPrompt) + if (failedCategories?.length > 0) { + throw new Error(`ChatGPt prompt failed moderation: ${failedCategories.join(", ")}`) + } + preferences.chatGptPrompt = req.body.chatGptPrompt.substring(0, 100).trim() + } + // User details to be updated. const data: Partial = { id: user.id,