{"id":28569868,"url":"https://github.com/workos/mastra-agents-meme-generator","last_synced_at":"2025-08-08T10:36:06.785Z","repository":{"id":296918156,"uuid":"992396636","full_name":"workos/mastra-agents-meme-generator","owner":"workos","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-03T22:21:31.000Z","size":13037,"stargazers_count":3,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-04T04:07:40.243Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/workos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-29T05:02:38.000Z","updated_at":"2025-06-03T23:12:57.000Z","dependencies_parsed_at":"2025-06-03T11:00:23.785Z","dependency_job_id":"49198515-724f-4deb-a34f-8dc4a8262bff","html_url":"https://github.com/workos/mastra-agents-meme-generator","commit_stats":null,"previous_names":["workos/ai-eng-world-faire-workshop","workos/mastra-agents-meme-generator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fmastra-agents-meme-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fmastra-agents-meme-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fmastra-agents-meme-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fmastra-agents-meme-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/workos","download_url":"https://codeload.github.com/workos/mastra-agents-meme-generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/workos%2Fmastra-agents-meme-generator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259118823,"owners_count":22808063,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-10T17:39:27.788Z","updated_at":"2025-06-10T17:39:29.158Z","avatar_url":"https://github.com/workos.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AI Pipelines and Agents in Pure TypeScript with Mastra.ai\n\nWelcome to this hands-on workshop! This project demonstrates how to build **production-ready AI agents and workflows** using Mastra to create a fun meme generation pipeline that turns workplace frustrations into shareable memes.\n\n## 🎬 Workshop Video Tutorial\n\nWatch the demo of this application runnning end to end:\n\n[![Video Thumbnail](https://img.youtube.com/vi/oZmaBSuxZVA/0.jpg)](https://www.youtube.com/watch?v=oZmaBSuxZVA)\n\n🎥 **Click above to watch the full workshop video!**\n\nWhile we've chosen a humorous implementation example, the **patterns, architecture, and Mastra framework** you'll learn here are ideal for creating **enterprise-grade agentic applications**. The same workflow concepts apply whether you're building customer support automation, data processing pipelines, or complex business logic orchestration.\n\n## 🎯 What You'll Learn\n\n- **Mastra Agents**: Build conversational AI agents that can understand user input\n- **Mastra Workflows**: Create modular workflow steps that can be chained together\n- **Structured Generation**: Use Vercel AI SDK with Zod schemas for reliable data extraction\n- **External API Integration**: Connect to meme services (Imgflip) for meme generation\n- **Agentic Workflows**: Chain multiple steps together to create complex workflows\n\n## 🧠 Understanding the Workflow\n\n### The Meme Generation Pipeline\n\nOur workshop demonstrates a complete agentic workflow:\n\n```mermaid\ngraph LR\n    A[User Input\u003cbr/\u003eWork Frustrations] --\u003e B[Extract Frustrations Step\u003cbr/\u003eStructured Generation]\n    B --\u003e C[Find Base Meme Step\u003cbr/\u003eImgflip API Search]\n    C --\u003e D[Generate Captions Step\u003cbr/\u003eAI Caption Creation]\n    D --\u003e E[Generate Meme Step\u003cbr/\u003eImgflip Caption API]\n    E --\u003e F[Shareable URL\u003cbr/\u003eReady to Share!]\n```\n\n### Key Components\n\n1. **Frustration Extraction Step**: Uses structured generation to parse user input into categorized frustrations\n2. **Meme Search Step**: Searches Imgflip's free API for appropriate base meme templates\n3. **Caption Generation Step**: Creates witty, contextual captions based on frustrations and meme template\n4. **Meme Generation Step**: Uses Imgflip's caption API to create memes with the base template and captions, returning a stable shareable URL\n\n## 🎭 Example Generated Memes\n\nHere are some actual memes generated by our workshop application, showcasing how work frustrations get transformed into shareable humor:\n\n### Open Office Nightmares → Workplace Reality\n\u003cimg src=\"img/good1.jpeg\" alt=\"Open floor plan noise meme\" width=\"400\"\u003e\n\n*When they move all the engineers to an open floor plan with noisy co-workers...*\n\n### Compensation Blues → The Talent Paradox  \n\u003cimg src=\"img/good2.png\" alt=\"Excellent but underpaid meme\" width=\"400\"\u003e\n\n*Being told you're excellent at your job but somehow still underpaid...*\n\n### The Helper's Dilemma → Salary Irony\n\u003cimg src=\"img/good3.jpg\" alt=\"Helping higher paid colleague meme\" width=\"400\"\u003e\n\n*When you refer an engineer who constantly asks for your help but gets paid more than you...*\n\n\u003cimg src=\"img/good4.jpeg\" alt=\"Salary disparity meme\" width=\"400\"\u003e\n\n*That awkward moment when your mentee's starting salary is higher than your current one...*\n\nThese examples demonstrate how our AI workflow transforms common workplace frustrations into contextually appropriate and genuinely funny memes that teams can actually share!\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Node.js 20.9.0+\n- OpenAI API key (for caption generation)\n- Optional: Imgflip account credentials (for better rate limits and reliability)\n- Basic knowledge of Next.js and TypeScript\n\n### 1. Clone and Install\n\n```bash\ngit clone \u003cyour-repo-url\u003e\ncd mastra-workshop-test\nnpm install\n```\n\n### 2. Environment Setup\n\nCreate a `.env` file with your API keys:\n\n```env\n# OpenAI Configuration (required for caption generation)\nOPENAI_API_KEY=your_openai_api_key_here\n\n# Optional: Imgflip credentials for meme generation (recommended for better reliability)\nIMGFLIP_USERNAME=your_imgflip_username\nIMGFLIP_PASSWORD=your_imgflip_password\n```\n\n**Note:** The app will work without Imgflip credentials using a default account, but may be rate limited.\n\n### 3. Start the Development Server\n\n```bash\nnpm run dev\n```\n\nVisit [http://localhost:4111](http://localhost:4111) to start generating memes!\n\n## 🤖 How It Works\n\n### The Meme Agent\n\nOur main agent understands user frustrations and orchestrates the meme generation process:\n\n```typescript\n// Simplified agent structure\nconst memeGeneratorAgent = new Agent({\n  name: 'MemeGenerator',\n  instructions: 'Help users turn their work frustrations into funny memes',\n  workflows: {\n    'meme-generation': memeGenerationWorkflow,\n  },\n});\n```\n\n### Workflow Architecture\n\nEach step in our workflow is designed to be:\n\n- **Modular**: Can be used independently or as part of the workflow\n- **Typed**: Uses Zod schemas for input/output validation\n- **Testable**: Can be tested in isolation using Mastra's built-in tools\n- **Reusable**: Can be composed into different workflows\n\n## 🛠️ Workflow Steps Deep Dive\n\n### 1. Extract Frustrations Step\n\n```typescript\nconst extractFrustrationsStep = createStep({\n  id: 'extract-frustrations',\n  description: 'Extract and categorize user frustrations from raw input',\n  inputSchema: z.object({\n    userInput: z.string().describe('Raw user input about work frustrations'),\n  }),\n  execute: async ({ inputData }) =\u003e {\n    // Uses Vercel AI SDK with structured generation\n    const result = await generateObject({\n      model: openai('gpt-4'),\n      schema: frustrationsSchema,\n      prompt: `Extract frustrations from: ${inputData.userInput}`,\n    });\n    return result.object;\n  },\n});\n```\n\n### 2. Find Base Meme Step\n\n```typescript\nconst findBaseMemeStep = createStep({\n  id: 'find-base-meme',\n  description: \"Get a diverse selection of meme templates from Imgflip's free API\",\n  inputSchema: frustrationsSchema.extend({\n    analysis: z.object({\n      message: z.string(),\n    }),\n  }),\n  execute: async ({ inputData }) =\u003e {\n    // Search Imgflip's free API for relevant meme templates\n    const response = await fetch('https://api.imgflip.com/get_memes');\n    const data = await response.json();\n    const selectedMemes = data.data.memes.slice(0, 10);\n    return { templates: selectedMemes };\n  },\n});\n```\n\n### 3. Generate Captions Step\n\n```typescript\nconst generateCaptionsStep = createStep({\n  id: 'generate-captions',\n  description: 'Generate meme captions based on frustrations and template',\n  inputSchema: z.object({\n    frustrations: frustrationsSchema,\n    baseTemplate: memeTemplateSchema,\n  }),\n  execute: async ({ inputData }) =\u003e {\n    // Generate contextual, funny captions using AI\n    const captions = await generateObject({\n      model: openai('gpt-4'),\n      schema: captionsSchema,\n      prompt: `Create funny captions for ${inputData.baseTemplate.name} based on: ${inputData.frustrations}`,\n    });\n    return captions.object;\n  },\n});\n```\n\n### 4. Generate Meme Step\n\n```typescript\nconst generateMemeStep = createStep({\n  id: 'generate-meme',\n  description: \"Create a meme using Imgflip's caption API with the selected template and captions\",\n  inputSchema: z.object({\n    baseTemplate: memeTemplateSchema,\n    captions: captionsSchema,\n  }),\n  execute: async ({ inputData }) =\u003e {\n    // Use Imgflip's caption_image API to create meme with specific template and text\n    const formData = new URLSearchParams();\n    formData.append('template_id', inputData.baseTemplate.id);\n    formData.append('username', process.env.IMGFLIP_USERNAME || 'imgflip_hubot');\n    formData.append('password', process.env.IMGFLIP_PASSWORD || 'imgflip_hubot');\n    formData.append('text0', inputData.captions.topText);\n    formData.append('text1', inputData.captions.bottomText);\n\n    const response = await fetch('https://api.imgflip.com/caption_image', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n      body: formData,\n    });\n    \n    const result = await response.json();\n    // Imgflip provides a stable, shareable URL that can be used directly\n    return { imageUrl: result.data.url, pageUrl: result.data.page_url };\n  },\n});\n```\n\n\n\n## 🧪 Testing Your Workflow\n\n### Local Testing with Mastra\n\nMastra provides excellent built-in capabilities for testing your workflows:\n\n```bash\n# Start the development server to test interactively\nnpm run dev\n\n# Visit the Mastra playground at http://localhost:4111\n# Use the chat interface to test the complete workflow\n```\n\n### Example Test Cases\n\n1. **Simple Frustration**: \"My meetings always run over time\"\n2. **Complex Frustration**: \"The deployment process is broken, code reviews take forever, and our standup meetings are pointless\"\n3. **Emotional Frustration**: \"I'm so tired of explaining the same thing over and over to different stakeholders\"\n\n## 🎨 Customization Ideas\n\n### Meme Styles\n\n- **Corporate Humor**: Professional-looking memes safe for work\n- **Developer Memes**: Programming and tech-specific templates\n- **Remote Work**: Memes about working from home challenges\n- **Meeting Memes**: Specifically about meeting frustrations\n\n### Integration Options\n\n- **Slack Bot**: Deploy as a Slack app for team use\n- **Teams Integration**: Microsoft Teams bot for enterprise\n- **Discord Bot**: For gaming/tech communities\n- **Web Widget**: Embeddable meme generator for websites\n\n## 📖 Learn More\n\n### Documentation\n\n- [Mastra Documentation](https://mastra.ai/docs)\n- [Vercel AI SDK](https://sdk.vercel.ai/docs)\n- [OpenAI API Documentation](https://platform.openai.com/docs)\n- [Imgflip API](https://imgflip.com/api)\n\n### Key Concepts\n\n- **Agent Orchestration**: How agents coordinate multiple workflow steps\n- **Structured Generation**: Reliable data extraction from LLMs\n- **Workflow Composition**: Building complex workflows from simple steps\n- **Error Handling**: Graceful failure and recovery in agentic systems\n- **Testing Strategies**: How to test AI-powered workflows\n\n## 🎉 Workshop Goals\n\nBy the end of this workshop, you'll have:\n\n- ✅ Built a complete agentic workflow with multiple specialized steps\n- ✅ Integrated external APIs (Imgflip, OpenAI)\n- ✅ Used structured generation for reliable data extraction\n- ✅ Created a fun, shareable application that solves real problems\n- ✅ Learned Mastra's agent and workflow patterns\n- ✅ Gained experience with AI-powered workflows and step composition\n\n## 🤝 Contributing\n\nFound an issue or want to improve the workshop? Please open an issue or submit a pull request!\n\n## 📄 License\n\nMIT License - feel free to use this code for your own projects and workshops.\n\n---\n\n**Happy meme generating!** 🎭 Turn those work frustrations into laughs and learn about agentic AI workflows in the process!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkos%2Fmastra-agents-meme-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fworkos%2Fmastra-agents-meme-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fworkos%2Fmastra-agents-meme-generator/lists"}