import { openai } from './setup'; export enum CustomizationType { PRES_TRAIL_SLIDE = 'trails', } interface PromptInfo { description: string; features: { name: string; description: string; values?: string[] }[]; } const prompts: { [key: string]: PromptInfo } = { trails: { description: 'We are customizing the properties and transition of a slide in a presentation. You are given the current properties of the slide in a json with the fields [title, presentation_transition, presentation_effect, config_zoom, presentation_effectDirection], as well as the prompt for how the user wants to change it. Return a json with the required fields: [title, presentation_transition, presentation_effect, config_zoom, presentation_effectDirection] by applying the changes in the prompt to the current state of the slide.', features: [], }, }; // Allows you to register properties that are customizable export const addCustomizationProperty = (type: CustomizationType, name: string, description: string, values?: string[]) => { values ? prompts[type].features.push({ name, description, values }) : prompts[type].features.push({ name, description }); }; // All the registered fields, make sure to update during registration, this // includes most fields but is not yet fully comprehensive export const gptSlideProperties = [ 'title', 'presentation_transition', 'presEaseFunc', 'presentation_effect', 'presentation_effectDirection', 'presEffectTiming', 'config_zoom', 'presPlayAudio', 'presentation_zoomText', 'presentation_hideBefore', 'presentation_hide', 'presentation_hideAfter', 'presentation_openInLightbox', ]; // Registers slide properties const setupPresSlideCustomization = () => { addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'title', 'is the title/name of the slide.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_transition', 'is a number in milliseconds for how long it should take to transition/move to a slide.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presEaseFunc', 'is the easing function for the movement to the slide.', ['Ease', 'Ease In', 'Ease Out', 'Ease Out', 'Ease In Out', 'Linear']); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_effect', 'is an effect applied to the slide when we transition to it.', ['None', 'Zoom', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_effectDirection', 'is what direction the effect is applied.', ['Enter from left', 'Enter from right', 'Enter from bottom', 'Enter from Top', 'Enter from center']); addCustomizationProperty( CustomizationType.PRES_TRAIL_SLIDE, 'presEffectTiming', "is a json object of the format: {type: string, stiffness: number, damping: number, mass: number}. Type is always “custom”. Controls the spring-based timing of the presentation effect animation. Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to match the user's description of how they want to animate the effect." ); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'config_zoom', 'is a number from 0 to 1.0 indicating the percentage we should zoom into the slide.'); // boolean values addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presPlayAudio', 'is a boolean value indicating if we should play audio when we go to the slide.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_zoomText', 'is a boolean value indicating if we should zoom into text selections when we go to the slide.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hideBefore', 'is a boolean value indicating if we should hide the slide before going to it.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hide', 'is a boolean value indicating if we should hide the slide during the presentation.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_hideAfter', 'is a boolean value indicating if we should hide the slide after going to it.'); addCustomizationProperty(CustomizationType.PRES_TRAIL_SLIDE, 'presentation_openInLightbox', 'is a boolean value indicating if we should open the slide in an overlay or lightbox view during the presentation.'); }; setupPresSlideCustomization(); export const getSlideTransitionSuggestions = async (inputText: string) => { /** * Prompt: Generate an entrance animations from slower and gentler * to bouncier and more high energy * * Format: * { * name: Slow Fade, Quick Flip, Springy * effect: BOUNCE * effectDirection: LEFT * timingConfig: { * } * } */ const prompt = "I want to generate four distinct types of slide effect animations. Return a json of the form {effect: string, direction: string, stiffness: number, damping: number, mass: number}[] with four elements. Effect is the type of animation; its only possible values are ['Zoom', 'Fade in', 'Bounce', 'Flip', 'Rotate', 'Roll']. Direction is the direction that the animation starts from; its only possible values are ['Enter from left', 'Enter from right', 'Enter from bottom', 'Enter from Top', 'Enter from center']. Stiffness, damping, and mass control the physics-based properties of spring animations. This is used to create a more natural-looking timing, bouncy effects, etc. Use spring physics to adjust these parameters to animate the effect."; const customInput = inputText ?? 'Make them as contrasting as possible with different effects and timings ranging from gentle to energetic.'; try { const response = await openai.chat.completions.create({ model: 'gpt-4', messages: [ { role: 'system', content: prompt }, { role: 'user', content: `${customInput}` }, ], temperature: 0, max_tokens: 1000, }); return response.choices[0].message?.content; } catch (err) { console.log(err); return 'Error connecting with API.'; } }; export const gptTrailSlideCustomization = async (inputText: string, properties: any | any[], applyToWhole?: boolean) => { let prompt = prompts.trails.description; prompts.trails.features.forEach(feature => { prompt += feature.name + ' ' + feature.description; if (feature.values) { prompt += `Its only possible values are [${feature.values.join(', ')}].`; } }); prompt += 'Set unchanged values to null. Please only return the json with these keys and their values.'; console.log('messages', [ { role: 'system', content: prompt }, { role: 'user', content: `Prompt: ${inputText}, Current properties: ${JSON.stringify(properties)}` }, ]); try { const response = await openai.chat.completions.create({ model: 'gpt-4', messages: [ { role: 'system', content: prompt }, { role: 'user', content: `Prompt: ${inputText}, Current properties: ${JSON.stringify(properties)}` }, ], temperature: 0, max_tokens: 1000, }); return response.choices[0].message?.content; } catch (err) { console.log(err); return 'Error connecting with API.'; } };