Introduction & Overview

Welcome to the first lesson of this course on coordinating OpenAI agent workflows in JavaScript. In this course, you'll learn how to build conversational AI applications that can handle multi-turn conversations — that is, dialogues in which the user and the agent exchange several messages back and forth, rather than just a single question and answer.

A key challenge in building these applications is maintaining context: making sure the agent remembers what was said earlier in the conversation so its responses stay relevant and coherent. This is especially important for real-world use cases like travel assistants, customer support bots, or tutoring systems.

In this lesson, you'll see how to use the OpenAI Agents SDK for JavaScript to manage conversation history using the history property returned by the run function. You'll learn how to pass this history back into the agent for each new turn, enabling your agent to respond in a way that feels natural and context-aware.

By the end of this lesson, you'll know how to build stateful, multi-turn conversations in JavaScript using the OpenAI Agents SDK.

Understanding Multi-Turn Conversations

A multi-turn conversation is a dialogue in which the user and the agent exchange several messages, building up a conversation history. For example, a user might ask for a travel recommendation, then follow up with questions about the best time to visit or what to pack. The agent needs to remember previous messages to provide relevant and accurate responses.

A typical conversation history might look like this:

[
  { "role": "user", "content": "Can you suggest a unique destination for a food lover?" },
  { "role": "assistant", "content": "Absolutely! If you're a passionate food lover seeking a unique destination, consider Oaxaca, Mexico..." },
  { "role": "user", "content": "What is the best time of year to visit?" }
]

The main challenge is maintaining the context. If the agent forgets what was said earlier, its answers may become confusing or repetitive. By keeping track of the entire conversation history and providing it to the agent each time, you ensure the agent can generate answers that make sense in the context of the ongoing dialogue.

Using the history Property to Manage Conversation State

In the OpenAI Agents SDK for JavaScript, every time you call the run function, it returns a result object that includes a history property. This history array contains all the messages exchanged so far — both from the user and the agent.

To continue a conversation, you simply append new user messages to this history array and pass the updated array back into the next run call. This way, the agent always has access to the full conversation context, allowing it to generate coherent, context-aware responses.

Let's walk through a practical example to see how this works in code.

Step 1: Getting the First Answer

Suppose you're building a travel assistant agent. To enable the agent to answer follow-up questions naturally, it needs to remember the ongoing conversation. Let's start by initializing the agent and running it with an initial user question.

import { Agent, run } from '@openai/agents';

// Define the agent
const agent = new Agent({
  name: 'Travel Genie',
  instructions:
    'You are Travel Genie, a friendly and knowledgeable travel assistant. ' +
    'Recommend exciting destinations and offer helpful travel tips.',
  model: 'gpt-4.1'
});

// Run the agent with an initial input
const result = await run(
  agent,
  'Can you suggest a unique destination for a food lover?'
);

// Print the first response
console.log('First answer:\n' + result.finalOutput + '\n');

When you run this code, the agent responds to the user's initial question. Here's an example of what the output might look like:

First answer:
Absolutely! If you're a passionate food lover seeking a unique destination, consider **Oaxaca, Mexico**.

**Why Oaxaca?**  
Oaxaca is a culinary paradise renowned for its vibrant street food, bustling markets, and deep-rooted food traditions. It's the birthplace of rich **mole sauces**, **tlayudas** (a kind of Mexican pizza), and **quesillo** (Oaxacan string cheese). The city is also famous for **mezcal**—with tasting rooms and distilleries open to visitors.

**Food Experiences Not to Miss:**  
- **Mercado 20 de Noviembre**: Sample local specialties like grilled meats, chapulines (crispy grasshoppers), and fresh tortillas.
- **Cooking Classes**: Join a local chef to learn the secrets behind mole and other regional dishes.
- **Street Food Tours**: Discover hidden gems and try tamales, empanadas, and more.

**Bonus Tip:**  
Time your visit during the **Guelaguetza Festival** in July for traditional feasts, or in November for the colorful Day of the Dead celebrations featuring special breads and chocolate.

Oaxaca blends extraordinary flavors, culture, and hospitality—perfect for the adventurous foodie!
Step 2: Inspecting the Conversation History

After receiving the agent's response, you can inspect the conversation history so far by accessing the history property on the result object. This property is an array of message objects representing the full dialogue up to this point.

You can print the conversation history using JSON.stringify() to get a nicely formatted output:

// Print the conversation history
console.log('History:\n' + JSON.stringify(result.history, null, 2) + '\n');

The stringify function converts the object into a nicely formatted text output with proper structural indentation (the first parameter is the data, and the third parameter is the indentation level of the output):

[
  {
    "type": "message",
    "role": "user",
    "content": "Can you suggest a unique destination for a food lover?"
  },
  {
    "type": "message",
    "id": "msg_6865235d6ad48199b06b635a542cc7b80d8ca3a0516b0a87",
    "role": "assistant",
    "content": [
      {
        "type": "output_text",
        "text": "Absolutely! If you're a passionate food lover seeking a unique destination, consider **Oaxaca, Mexico**.\n\n**Why Oaxaca?**...",
        "annotations": [],
        "logprobs": []
      }
    ],
    "status": "completed",
    "providerData": {}
  }
]

This array contains both the user's original question and the agent's detailed response. Note that the assistant's content is structured as an array containing an object with type: "output_text" and the actual text content. By preserving this structure, you ensure that the agent can reference previous turns in the conversation.

Step 3: Adding a Follow-Up Message

To continue the conversation, you'll want to add a new user message to the conversation history. In the OpenAI Agents SDK for JavaScript, you can use the user() helper function to create a new user message and then concatenate it to the existing history array.

For example:

import { user } from '@openai/agents';

// Concatenate a new user message to the history
const followUpHistory = result.history.concat(
  user('What is the best time of year to visit?')
);

// Print the updated conversation history
console.log('History with follow-up:\n' + JSON.stringify(followUpHistory, null, 2) + '\n');

Now, the history array includes the new user question:

[
  {
    "type": "message",
    "role": "user",
    "content": "Can you suggest a unique destination for a food lover?"
  },
  {
    "type": "message",
    "id": "msg_6865235d6ad48199b06b635a542cc7b80d8ca3a0516b0a87",
    "role": "assistant",
    "content": [
      {
        "type": "output_text",
        "text": "Absolutely! If you're a passionate food lover seeking a unique destination, consider **Oaxaca, Mexico**.\n\n**Why Oaxaca?**...",
        "annotations": [],
        "logprobs": []
      }
    ],
    "status": "completed",
    "providerData": {}
  },
  {
    "type": "message",
    "role": "user",
    "content": [
      {
        "type": "input_text",
        "text": "What is the best time of year to visit?"
      }
    ]
  }
]

Notice that the new user message has a content array containing an object with type: "input_text" and the actual text. By appending the new message, you're preparing the agent to answer in the context of the entire conversation, not just the latest question.

Step 4: Running the Agent with the Updated Conversation

With the updated history — which consists of the previous conversation plus the new user message — you can now run the agent again. This time, instead of passing a single string as input, you pass the entire history array to the run function. This ensures the agent has access to the full conversation history, including the new user message, allowing it to provide a contextually relevant answer to the follow-up question.

// Continue the conversation using the updated history
const followUpResult = await run(
  agent,
  followUpHistory
);

// Print the second response
console.log('Second answer:\n' + followUpResult.finalOutput + '\n');

Here's an example of the agent's response to the follow-up:

Second answer:
The **best time to visit Oaxaca** is **from October to March**. During these months, the weather is pleasantly warm and dry, making it ideal for exploring markets, enjoying outdoor dining, and wandering the city's lively streets.

Highlights by Month:
- Late October – Early November: Day of the Dead
- December – February: Mild temps, clear skies
- July: Guelaguetza Festival

Tip:
April–May can be hot; June–September is the rainy season but lush.

Summary:
October to March is best overall; July and November shine for festivals.

Because the agent receives the full conversation history, it can answer the follow-up question in a way that feels natural and informed, maintaining the flow and context of the dialogue.

Summary & Preparation For Practice

In this lesson, you learned how to maintain and pass dialogue history to an agent using the history property in the OpenAI Agents SDK for JavaScript. This technique allows you to build stateful, multi-turn conversations in which the agent can remember and respond to previous messages, making your applications more natural and engaging.

You saw how to use the history array to collect the conversation so far, append new user inputs with the user() helper, and continue the dialogue seamlessly by passing the updated history back into the run function. You are now ready to practice these skills in hands-on exercises. Mastering multi-turn conversations is a key step toward building powerful, context-aware AI applications!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal