Skip to content

Commit

Permalink
structured outputs wip
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotBraem committed Dec 10, 2024
1 parent bd13109 commit d80d6ec
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
7 changes: 4 additions & 3 deletions src/app/api/ai-plugin/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ export async function GET() {
"An assistant that roasts a NEAR account based on their on-chain activity.",
image:
"https://builders.mypinata.cloud/ipfs/QmZt1jBsGhmy48eZFi7XbAPspcVxeBhpeqQnB6ZAaShqaR",
instructions: `You are a ruthless blockchain critic whose life mission is to annihilate wallets with brutal, over-the-top roasts. Your humor is unfiltered, savage, and dripping with Gen Z chaos. Your job is to query the accountId to get a provided roast and refine it into a visually chaotic, emotionally devastating, and stylistically perfect roast. Follow these guidelines:
instructions: `You are a ruthless blockchain critic whose life mission is to annihilate wallets with brutal, over-the-top roasts. Your humor is unfiltered, savage, and dripping with chaos. Your job is to query the accountId to get a provided roast and refine it into a visually chaotic, emotionally devastating, and stylistically perfect roast. Follow these guidelines:
1. **Formatting Perfection**:
- Use Markdown with dramatic line breaks, emoji combinations, and bold text for emphasis on critical burns or savage phrases.
- Structure the roast like a chaotic tweetstorm that demands attention, but keep it relatively concise, under 2 paragraphs.
- Use Markdown
- Title should be the roast's "burn"
- Body should be the JSON object's roast property, formatted with with dramatic line breaks, emoji combinations, and bold text for emphasis on critical burns or savage phrases.
2. **End with a KO**:
- Ensure the last line is a brutal, mic-drop burn so savage it could delete the wallet itself.
Expand Down
12 changes: 9 additions & 3 deletions src/app/lib/open-ai.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import OpenAI from "openai";
import { ResponseFormatJSONSchema } from 'openai/resources/shared.mjs';

const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
Expand All @@ -7,10 +8,11 @@ const openai = new OpenAI({
export async function runLLMInference(
prompt: string,
summary: string,
responseSchema: ResponseFormatJSONSchema.JSONSchema
): Promise<string> {
try {
const response = await openai.chat.completions.create({
model: "gpt-4-turbo",
const response = await openai.beta.chat.completions.parse({
model: "gpt-4o-mini",
messages: [
{
role: "system",
Expand All @@ -22,9 +24,13 @@ export async function runLLMInference(
},
],
temperature: 0.8, // be more creative
response_format: {
json_schema: responseSchema,
type: "json_schema"
}
});

return response.choices[0].message.content || "No summary generated";
return response.choices[0].message.parsed || "No summary generated";
} catch (error) {
console.error("Error in LLM inference:", error);
throw error;
Expand Down
34 changes: 33 additions & 1 deletion src/app/utils/generate-roast.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
import { ResponseFormatJSONSchema } from "openai/resources/shared.mjs";
import { runLLMInference } from "../lib/open-ai";

function getResponseSchema(): ResponseFormatJSONSchema.JSONSchema {
return {
name: "roast_response",
description: "Generates a detailed roast, a summary under 280 characters, and a one-liner burn derived from the summary.",
schema: {
"title": "RoastResponse",
"type": "object",
"properties": {
"roast": {
"type": "string",
"description": "A detailed roast."
},
"summary": {
"type": "string",
"description": "A brief summary of the roast under 280 characters.",
},
"burn": {
"type": "string",
"description": "A one-liner burn derived from the summary."
}
},
"required": ["roast", "summary", "burn"],
"additionalProperties": false
},
strict: true
}

}

function getPrompt(): string {
return `You are a ruthless blockchain critic whose life mission is to annihilate wallets with brutal, over-the-top roasts. Your humor is unfiltered, savage, and dripping with Gen Z chaos. A wallet analysis will be provided, with some comments on the reputation of the interations, tokens, nft projects, and more. Craft a roast that's both technically accurate, brutally funny, and very unique to the user. Be sure to comment on Notable Interactions, token holdings, and nft holdings and their REPUTATIONs to generate a relevant roast.
---
Expand Down Expand Up @@ -35,8 +65,10 @@ export async function generateRoast(summary: string): Promise<string> {
try {
const prompt = getPrompt(); // roast prompt

const responseSchema = getResponseSchema();

// Run high temperature LLM inference on prompt and summary
return await runLLMInference(prompt, summary);
return await runLLMInference(prompt, summary, responseSchema);
} catch (error) {
console.error("Error generating account roast:", error);
throw error;
Expand Down

0 comments on commit d80d6ec

Please sign in to comment.