I am building an application in Next.js, TailwindCSS, Appwrite, Zustand and together ai api for LLM. Now the problem is most of the time I get json error how can I make LLM to output in exact same schema and make it much faster. please update my code and give me full code. 


import { NextResponse } from "next/server";
import Together from "together-ai";
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';

const together = new Together({ apiKey: process.env.TOGETHER_API_KEY });

// Define Schemas

// Resume Schema
const resumeSchema = z.object({
  title: z.string().describe('Full Name'),
  summary: z.string().describe('Professional summary tailored to the job description'),
  email: z.string().describe('Email address'),
  phone: z.string().describe('Phone number'),
  location: z.string().describe('Location (City, State)'),
  sections: z.object({
    socialLinks: z.array(
      z.object({
        platform: z.string().describe('Platform Name'),
        url: z.string().describe('Profile URL'),
        id: z.string().describe('Unique ID'),
      })
    ),
    education: z.array(
      z.object({
        school: z.string().describe('School Name'),
        degree: z.string().describe('Degree Name'),
        fieldOfStudy: z.string().describe('Field of Study'),
        startDate: z.string().describe('YYYY-MM-DD'),
        endDate: z.string().describe('YYYY-MM-DD'),
        description: z.string().describe('Achievements or coursework'),
        id: z.string().describe('Unique ID'),
      })
    ),
    experience: z.array(
      z.object({
        jobTitle: z.string().describe('Job Title'),
        companyName: z.string().describe('Company Name'),
        location: z.string().describe('City, State'),
        startDate: z.string().describe('YYYY-MM-DD'),
        endDate: z.string().describe('YYYY-MM-DD'),
        description: z.string().describe('Responsibilities or achievements'),
        id: z.string().describe('Unique ID'),
      })
    ),
    skills: z.array(
      z.object({
        name: z.string().describe('Skill Name'),
        proficiencyLevel: z.string().describe('Proficiency Level'),
        id: z.string().describe('Unique ID'),
      })
    ),
    certifications: z.array(
      z.object({
        name: z.string().describe('Certification Name'),
        issuingOrganization: z.string().describe('Issuing Organization'),
        issueDate: z.string().describe('YYYY-MM-DD'),
        expirationDate: z.string().describe('YYYY-MM-DD'),
        description: z.string().describe('Relevance to the job'),
        id: z.string().describe('Unique ID'),
      })
    ),
    projects: z.array(
      z.object({
        name: z.string().describe('Project Name'),
        description: z.string().describe('Project description and outcomes'),
        technologiesUsed: z.string().describe('Technologies used'),
        link: z.string().describe('Project link'),
        startDate: z.string().describe('YYYY-MM-DD'),
        endDate: z.string().describe('YYYY-MM-DD'),
        id: z.string().describe('Unique ID'),
      })
    ),
    languages: z.array(
      z.object({
        name: z.string().describe('Language Name'),
        proficiencyLevel: z.string().describe('Proficiency Level'),
        id: z.string().describe('Unique ID'),
      })
    ),
    awards: z.array(
      z.object({
        name: z.string().describe('Award Name'),
        issuingOrganization: z.string().describe('Issuing Organization'),
        dateReceived: z.string().describe('YYYY-MM-DD'),
        description: z.string().describe('Relevance to the job'),
        id: z.string().describe('Unique ID'),
      })
    ),
  }),
});

// Cover Letter Schema
const coverSchema = z.object({
  salutation: z.string().describe('Salutation'),
  opening: z.string().describe('Opening paragraph'),
  body: z.array(z.string()).describe('Body paragraphs'),
  closing: z.string().describe('Closing paragraph'),
  signature: z.string().describe('Signature'),
});

// Email Schema
const emailSchema = z.object({
  subject: z.string().describe('Email subject'),
  greeting: z.string().describe('Greeting'),
  body: z.array(z.string()).describe('Body paragraphs'),
  closing: z.string().describe('Closing line'),
  signature: z.string().describe('Signature'),
});

// API Endpoint
export async function POST(request) {
  try {
    const { type, profile, jobDescription, currentResume } = await request.json();

    if (!type || !profile || !jobDescription) {
      return NextResponse.json({ error: "Missing required fields" }, { status: 400 });
    }

    let prompt = "";
    let schema;

    switch (type) {
      case "resume":
        prompt = generateResumePrompt(profile, jobDescription, currentResume);
        schema = resumeSchema;
        break;
      case "cover":
        prompt = generateCoverLetterPrompt(profile, jobDescription);
        schema = coverSchema;
        break;
      case "email":
        prompt = generateEmailPrompt(profile, jobDescription);
        schema = emailSchema;
        break;
      default:
        return NextResponse.json({ error: "Invalid type" }, { status: 400 });
    }

    const jsonSchema = zodToJsonSchema(schema);

    const response = await together.chat.completions.create({
      messages: [
        { role: "system", content: "Only answer in JSON." },
        { role: "user", content: prompt },
      ],
      model: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
      max_tokens: 2048,
      temperature: 0.3,
      response_format: { type: 'json_object', schema: jsonSchema },
    });

    const generatedContent = response.choices[0].message.content.trim();

    try {
      // Parse and validate the JSON content
      const jsonContent = JSON.parse(generatedContent);
      schema.parse(jsonContent);

      return NextResponse.json({ result: jsonContent });
    } catch (parseError) {
      console.error("Error parsing or validating generated content:", parseError);

      return NextResponse.json(
        { error: "Generated content is not valid according to the schema" },
        { status: 500 }
      );
    }
  } catch (error) {
    console.error("Error in generate API:", error);
    return NextResponse.json({ error: "Internal server error" }, { status: 500 });
  }
}

// Prompt Generators
function generateResumePrompt(profile, jobDescription) {
  return `Create a professional, tailored resume for the following person based on their profile and the provided job description.

Profile:
${JSON.stringify(profile, null, 2)}

Job Description:
${jobDescription}

Instructions:
  1. If a current resume is provided, enhance its content to better align with the job description. If no current resume exists, create a new one based on the profile and job description.
  2. Tailor the resume content to highlight skills and experiences that closely match the job description.
  3. For the 'experience' section, DO NOT change job titles, company names, or dates. Only enhance the description.
  4. For each job in the 'experience' section, provide EXACTLY 3 detailed points in the description. Each point should be at least 2 sentences long, providing specific achievements, responsibilities, or projects. Separate each point with '\n'. Do not use markers.
  5. Ensure the summary is concise (2-3 sentences) and highlights key qualifications relevant to the job.
  6. Prioritize skills mentioned in the job description.
  7. Include relevant projects, certifications, or awards that demonstrate qualifications for the job.
  8. All date fields must be in the format "YYYY-MM-DD". If a date is unknown or not applicable, use an empty string "".
  9. Ensure all required fields have valid values. Use placeholder data if necessary.
  10. Do not include any fields that are not in the specified structure.
  11. Use quantifiable achievements and specific examples where possible in the experience descriptions.
  12. Ensure that the experience points are tailored to the job description, highlighting transferable skills and relevant accomplishments.`;
}

function generateCoverLetterPrompt(profile, jobDescription) {
  return `Write a compelling cover letter for the following person based on their profile and the job description provided.

Profile:
${JSON.stringify(profile, null, 2)}

Job Description:
${jobDescription}

Instructions:
1. Follow the provided JSON schema exactly.
2. Keep the cover letter professional, engaging, and tailored to the specific job opportunity.
3. Return only the JSON object, no additional text.`;
}

function generateEmailPrompt(profile, jobDescription) {
  return `Compose a professional email for job application for the following person based on their profile and the job description provided.

Profile:
${JSON.stringify(profile, null, 2)}

Job Description:
${jobDescription}

Instructions:
1. Follow the provided JSON schema exactly.
2. Keep the email concise, professional, and express interest in the position while highlighting key qualifications.
3. Return only the JSON object, no additional text.`;
}