Change font
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
import { get, omit, tryit } from "radash";
|
||||
import { get, omit } from "radash";
|
||||
import { OpenAI } from "openai";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
const db = useDrizzle();
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
const ai = hubAI();
|
||||
const openai = new OpenAI({
|
||||
apiKey: config.openaiApiKey,
|
||||
});
|
||||
|
||||
const user = await db.query.users.findFirst({
|
||||
where: (f, o) => o.eq(f.id, body.owner_id),
|
||||
@@ -19,65 +23,93 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
const strava = await useStrava(body.owner_id);
|
||||
|
||||
const activity = (await strava!(`/activities/${body.object_id}`)) as any;
|
||||
const [, activity] = await strava!<any>(`/activities/${body.object_id}`);
|
||||
|
||||
const promptActivity = `
|
||||
type: ${get(activity, "type")}
|
||||
distance: ${get(activity, "distance")}m
|
||||
moving time: ${get(activity, "moving_time")}sec
|
||||
elapsed time: ${get(activity, "elapsed_time")}sec
|
||||
total elevation gain: ${get(activity, "total_elevation_gain")}m
|
||||
start (local): ${get(activity, "start_date_local")}
|
||||
trainer: ${get(activity, "trainer")}
|
||||
commute: ${get(activity, "commute")}
|
||||
calories: ${get(activity, "calories")}
|
||||
`;
|
||||
const aiResponse = await openai.chat.completions.create({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [
|
||||
{
|
||||
role: "user",
|
||||
content: `
|
||||
Generate a title and a short description for my strava activity. Use my preferred language.
|
||||
Use ${user?.preferences.data.tone} tone to generate content.
|
||||
Add emojis unless tone is set to minimalist.
|
||||
|
||||
const [aiError, aiResponse] = await tryit(ai.run)(
|
||||
"@cf/meta/llama-3.1-8b-instruct",
|
||||
{
|
||||
response_format: {
|
||||
type: "json_schema",
|
||||
json_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: "string",
|
||||
description: "string",
|
||||
My user profile:
|
||||
Sex: ${user?.sex}
|
||||
Weight: ${user?.weight}
|
||||
Language: ${user?.preferences.data.language}
|
||||
|
||||
Activity notes:
|
||||
distance is in meters, time is in seconds, don't include average speed. Convert time to hours or minutes, whatever's closer.
|
||||
The activity data in json format from strava:
|
||||
${JSON.stringify(
|
||||
omit(activity, [
|
||||
"laps",
|
||||
"segment_efforts",
|
||||
"splits_metric",
|
||||
"splits_standard",
|
||||
"hide_from_home",
|
||||
"available_zones",
|
||||
"map",
|
||||
"start_date_local",
|
||||
"gear",
|
||||
"stats_visibility",
|
||||
"embed_token",
|
||||
"name",
|
||||
"description",
|
||||
]),
|
||||
)}
|
||||
`,
|
||||
},
|
||||
],
|
||||
tools: [
|
||||
{
|
||||
type: "function",
|
||||
function: {
|
||||
name: "generate_strava_meta",
|
||||
description: "Generates Strava metadata.",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
title: {
|
||||
type: "string",
|
||||
description: "The title of the activity",
|
||||
},
|
||||
description: {
|
||||
type: "string",
|
||||
description: "A short description of the activity",
|
||||
},
|
||||
},
|
||||
required: ["title", "description"],
|
||||
},
|
||||
required: ["title", "description"],
|
||||
},
|
||||
},
|
||||
prompt: `
|
||||
Generate a title and a short description for my strava activity. Use my preferred language.
|
||||
Use ${user?.preferences.data.tone} tone to generate content.
|
||||
Add emojis unless tone is set to minimalist.
|
||||
|
||||
My user profile:
|
||||
Sex: ${user?.sex}
|
||||
Weight: ${user?.weight}
|
||||
Language: ${user?.preferences.data.language}
|
||||
|
||||
The activity data:
|
||||
${promptActivity}
|
||||
`,
|
||||
},
|
||||
);
|
||||
|
||||
console.log(
|
||||
omit(activity, [
|
||||
"map",
|
||||
"laps",
|
||||
"stats_visibility",
|
||||
"embed_token",
|
||||
"private_note",
|
||||
]),
|
||||
);
|
||||
|
||||
await strava!(`activities/${body.object_id}`, {
|
||||
method: "PUT",
|
||||
body: {
|
||||
name: get(aiResponse, "response.title"),
|
||||
description: get(aiResponse, "response.description"),
|
||||
],
|
||||
tool_choice: {
|
||||
type: "function",
|
||||
function: {
|
||||
name: "generate_strava_meta",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const responseObject = JSON.parse(
|
||||
get(aiResponse, "choices.0.message.tool_calls.0.function.arguments"),
|
||||
) as { title: string; description: string };
|
||||
|
||||
const [stravaError] = await strava!(`activities/${body.object_id}`, {
|
||||
method: "PUT",
|
||||
body: {
|
||||
name: responseObject.title,
|
||||
description: responseObject.description,
|
||||
},
|
||||
});
|
||||
|
||||
if (stravaError) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
message: `Strava API: ${stravaError.message}`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { get, isEmpty } from "radash";
|
||||
import { get, isEmpty, tryit } from "radash";
|
||||
import { isAfter } from "@formkit/tempo";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { URLSearchParams } from "url";
|
||||
@@ -57,10 +57,12 @@ export const useStrava = async (userId: number) => {
|
||||
.where(eq(tables.tokens.userId, userId));
|
||||
}
|
||||
|
||||
return $fetch.create({
|
||||
baseURL: "https://www.strava.com/api/v3/",
|
||||
onRequest({ options }) {
|
||||
options.headers.set("Authorization", `Bearer ${tokens?.accessToken}`);
|
||||
},
|
||||
});
|
||||
return tryit(
|
||||
$fetch.create({
|
||||
baseURL: "https://www.strava.com/api/v3/",
|
||||
onRequest({ options }) {
|
||||
options.headers.set("Authorization", `Bearer ${tokens?.accessToken}`);
|
||||
},
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user