I am building an application in Next.js, TailwindCSS, Appwrite, and Zustand. Now update my api so this genrates extact same json everytime according to the doc code and remeber I am coding in js and example is tpyescript

EXAMPLE CODE
JSON Mode
Learn how to use JSON mode to get structured outputs from LLMs including Llama 3.1.

Suggest Edits
JSON mode corrals the LLM into outputting JSON conforming to a provided schema. To activate JSON mode, provide the response_format parameter to the Chat Completions API with {"type": "json_object"}. The JSON Schema can be specified with the schema property of response_format.

Supported models
meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo
meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo
mistralai/Mixtral-8x7B-Instruct-v0.1
mistralai/Mistral-7B-Instruct-v0.1
JSON mode example
When using JSON mode, always instruct the model to produce JSON, either in a system or user message. This is very important so that it only responds in JSON, along with providing the response_format parameter.

With JSON mode, you can specify a schema for the output of the LLM. In Python, we'll do this with Pydantic and in TypeScript, we'll do this with Zod. Here's an example of JSON mode with Python using Llama 3.1.

Python
TypeScript
curl

import Together from 'together-ai';
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';

const together = new Together();

// Defining the schema we want our data in
const voiceNoteSchema = z.object({
title: z.string().describe('A title for the voice note'),
summary: z
.string()
.describe('A short one sentence summary of the voice note.'),
actionItems: z
.array(z.string())
.describe('A list of action items from the voice note'),
});
const jsonSchema = zodToJsonSchema(voiceNoteSchema, 'voiceNoteSchema');

async function main() {
const transcript =
"Good morning! It's 7:00 AM, and I'm just waking up. Today is going to be a busy day, so let's get started. First, I need to make a quick breakfast. I think I'll have some scrambled eggs and toast with a cup of coffee. While I'm cooking, I'll also check my emails to see if there's anything urgent.";
const extract = await together.chat.completions.create({
messages: [
{
role: 'system',
content:
'The following is a voice message transcript. Only answer in JSON.',
},
{
role: 'user',
content: transcript,
},
],
model: 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo',
// @ts-ignore
response_format: { type: 'json_object', schema: jsonSchema },
});

if (extract?.choices?.[0]?.message?.content) {
const output = JSON.parse(extract?.choices?.[0]?.message?.content);
console.log(output);
return output;
}
return 'No output.';
}

main();

{
title: 'Morning Routine',
actionItems: [ 'Make breakfast', 'Check emails' ],
summary: 'The speaker is starting their day by making breakfast and checking their emails.'
}


API CODE
import { NextResponse } from "next/server";
import Together from "together-ai";

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

export async function POST(request) {
  try {
    const { action, ...data } = await request.json();

    switch (action) {
      case "regenerate":
        return await handleRegenerate(data);
      case "chat":
        return await handleChat(data);
      default:
        return NextResponse.json({ error: "Invalid action" }, { status: 400 });
    }
  } catch (error) {
    console.error("Error in API:", error);
    return NextResponse.json(
      { error: error.message || "Internal server error" },
      { status: 500 }
    );
  }
}

async function handleRegenerate({
  selectedSections,
  profile,
  jobDescription,
  currentResume,
  message,
  originalSections,
}) {
  if (
    !selectedSections ||
    !profile ||
    !jobDescription ||
    !currentResume ||
    !originalSections ||
    !message
  ) {
    return NextResponse.json(
      { error: "Missing required fields" },
      { status: 400 }
    );
  }

  const prompt = generateRegenerationPrompt(
    selectedSections,
    profile,
    jobDescription,
    currentResume,
    message,
    originalSections
  );

  const response = await together.chat.completions.create({
    messages: [{ role: "user", content: prompt }],
    model: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
    max_tokens: 1024,
    temperature: 0.1,
  });

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

  try {
    const jsonContent = JSON.parse(jsonString);
    const validatedContent = validateResumeContent(jsonContent);

    const replyPrompt = generateReplyPrompt(
      selectedSections,
      originalSections,
      validatedContent,
      message
    );

    const replyResponse = await together.chat.completions.create({
      messages: [{ role: "user", content: replyPrompt }],
      model: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
      max_tokens: 1024,
      temperature: 0.1,
    });

    const reply = replyResponse.choices[0].message.content.trim();

    return NextResponse.json({ result: validatedContent, reply });
  } catch (parseError) {
    console.error("Error parsing generated content:", parseError);
    return NextResponse.json(
      { error: "Generated content is not valid JSON", generatedContent },
      { status: 500 }
    );
  }
}

async function handleChat({ message, chatHistory, resume, jobDescription }) {
  if (!message || !chatHistory || !resume || !jobDescription) {
    return NextResponse.json(
      { error: "Missing required fields" },
      { status: 400 }
    );
  }

  const formattedHistory = chatHistory.map((msg) => ({
    role: msg.type === "user" ? "user" : "assistant",
    content: msg.content,
  }));

  const systemMessage = `
    You are a helpful assistant for resume and job application related queries.
    You have access to the following information:
    Resume: ${JSON.stringify(resume, null, 2)}
    Job Description: ${jobDescription}
    Please use this information to provide accurate and tailored responses to the user's questions about their resume and job application.
  `;

  const response = await together.chat.completions.create({
    messages: [
      { role: "system", content: systemMessage },
      ...formattedHistory,
      { role: "user", content: message },
    ],
    model: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
    max_tokens: 1024,
    temperature: 0.1,
  });

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

  return NextResponse.json({ reply });
}

const sectionPrompts = {
  summary:
    "Update the summary to highlight key achievements and skills relevant to the job description.",
  experience:
    "Enhance the experience section to emphasize relevant responsibilities and accomplishments.",
  skills:
    "Modify the skills section to showcase skills that align closely with the job requirements.",
  education:
    "Adjust the education section to highlight relevant courses or honors.",
};

function generateRegenerationPrompt(
  selectedSections,
  profile,
  jobDescription,
  currentResume,
  message,
  originalSections
) {
  const sectionInstructions = selectedSections
    .map((section) => {
      const instruction = sectionPrompts[section] || "";
      return `Section: ${section}\nInstruction: ${instruction}\nOriginal Content: ${JSON.stringify(
        originalSections[section],
        null,
        2
      )}`;
    })
    .join("\n\n");

  return `
You are a resume writing assistant.

**Task**: Regenerate the following sections of the resume based on the provided information. Only modify the selected sections.

**Selected Sections**: ${selectedSections.join(", ")}

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

**Job Description**:
${jobDescription}

**Current Resume**:
${JSON.stringify(currentResume, null, 2)}

**User Message**:
${message}

**Instructions**:
For each of the selected sections, follow these specific instructions:
${sectionInstructions}

**General Instructions**:
- Only modify the sections specified in the **Selected Sections**.
- Maintain the same structure and format as the current resume.
- Tailor the content to better match the job description and highlight relevant skills and experiences.
- Ensure that the regenerated sections seamlessly integrate with the rest of the resume.
- **Important**: Do not include any text outside of the JSON object.
- **Return only the updated resume as a valid JSON object. Do not include any additional text or explanations.**

**Expected JSON Structure**:

\`\`\`json
{
  "title": "Full Name",
  "summary": "Professional summary...",
  "email": "email@example.com",
  "phone": "+1234567890",
  "location": "City, Province",
  "sections": {
    "socialLinks": [ ... ],
    "education": [ ... ],
    "experience": [ ... ],
    "skills": [ ... ],
    "certifications": [ ... ],
    "projects": [ ... ],
    "languages": [ ... ],
    "awards": [ ... ]
  }
}
\`\`\`

**Remember**: Return only the JSON object. Do not include any explanations, comments, or additional text.
`;
}



function generateReplyPrompt(
  selectedSections,
  originalSections,
  validatedContent,
  userMessage
) {
  const regeneratedSections = selectedSections.reduce((acc, section) => {
    acc[section] = validatedContent.sections[section];
    return acc;
  }, {});

  return `
    You have just regenerated the following sections of a resume: ${selectedSections.join(", ")}.
    Here are the original sections: ${JSON.stringify(originalSections, null, 2)}
    And here are the regenerated sections: ${JSON.stringify(regeneratedSections, null, 2)}
    Provide a brief summary of the changes made and any suggestions for further improvements.
    Address the user's request to "${userMessage}".
  `;
}

function extractJson(text) {
  const jsonRegex = /({[\s\S]*})/;
  const match = text.match(jsonRegex);
  if (match && match[1]) {
    return match[1];
  }
  throw new Error("JSON data not found in the generated content");
}

function validateResumeContent(content) {
  const requiredFields = [
    "title",
    "summary",
    "email",
    "phone",
    "location",
    "sections",
  ];
  const requiredSections = [
    "socialLinks",
    "education",
    "experience",
    "skills",
    "certifications",
    "projects",
    "languages",
    "awards",
  ];

  requiredFields.forEach((field) => {
    if (!content[field]) {
      content[field] = "";
    }
  });

  if (!content.sections || typeof content.sections !== "object") {
    content.sections = {};
  }

  requiredSections.forEach((section) => {
    if (!content.sections[section] || !Array.isArray(content.sections[section])) {
      content.sections[section] = [];
    }
  });

  requiredSections.forEach((section) => {
    content.sections[section] = content.sections[section].map((item) => {
      const validatedItem = { ...item, id: item.id || generateUniqueId() };
      ["startDate", "endDate", "issueDate", "expirationDate", "dateReceived"].forEach((dateField) => {
        if (validatedItem[dateField]) {
          validatedItem[dateField] = validateDate(validatedItem[dateField]);
        }
      });
      return validatedItem;
    });
  });

  return content;
}

function validateDate(dateString) {
  if (!dateString || dateString.trim() === "") return "";

  const date = new Date(dateString);
  if (isNaN(date.getTime())) return "";

  return date.toISOString().split("T")[0];
}


function generateUniqueId() {
    return Date.now().toString() + Math.random().toString(36).substr(2, 9);
}