> ## Documentation Index
> Fetch the complete documentation index at: https://docs.freeplay.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi Prompt Chain

> Chain multiple prompts together in a session with Freeplay observability.

### 1. Configure your Environment

Configure environment variables and create your freeplay session

### 2. Create a Freeplay Session

Create a Freeplay Session that we will use to tie together all completions in the Chain

### 3. Run the first Completion

* Fetch and format the first prompt
* Call your LLM
* Extract the needed results

### 4. Record the first Completion to Freeplay

* Record to Freeplay

### 5. Run second Completion

* Fetch and format second prompt using output from the first
* Call your LLM provider
* Record to Freeplay

## Examples

<CodeGroup>
  ```javascript Node theme={null}
  import Freeplay, { getCallInfo, getSessionInfo } from "freeplay";
  import OpenAI from "openai";
  import * as dotenv from "dotenv";

  // confgure neccesaary environment variables
  let projectId = process.env["FREEPLAY_PROJECT_ID"];
  let freeplayApiKey = process.env["FREEPLAY_API_KEY"];
  let freeplayUrl = process.env["FREEPLAY_URL"];
  let openaiApiKey = process.env["OPENAI_API_KEY"];
  const openai = new OpenAI(process.env["OPENAI_API_KEY"]);

  // instantiate freeplay client
  const fpClient = new Freeplay({
      freeplayApiKey: freeplayApiKey,
      baseUrl: freeplayUrl,
  });

  // create a freeplay session
  // we will tie all completions in the chain to this session
  let session = fpClient.sessions.create({});

  // fetch the first prompt
  // generate an album title for a pop star
  const prompt_varsA = {"pop_star": "Taylor Swift"};
  const formattedPromptA = await fpClient.prompts.getFormatted({
      projectId: projectID,
      templateName: "album_bot",
      environment: "latest",
      variables: {"pop_star": "Taylor Swift"},
  });

  let start = new Date();
  const chatCompletionA = await openai.chat.completions.create({
      messages: formattedPromptA.llmPrompt,
      model: formattedPromptA.promptInfo.model,
    	...formattedPrompt.promptInfo.modelParameters
  });
  let end = new Date();

  // get the album name
  let album_name = chatCompletionA.choices[0].message.content;

  // record to freeplay
  fpClient.recordings.create({
      allMessages: formattedPromptA.allMessages({
          role: chatCompletionA.choices[0].message.role,
          content: chatCompletionA.choices[0].message.content,
      }),
      inputs: prompt_varsA,
      sessionInfo: getSessionInfo(session), // tie the completion to the session
      promptInfo: formattedPromptA.promptInfo,
      callInfo: getCallInfo(formattedPromptA.promptInfo, start, end)
  });

  // fetch the second prompt
  // generate the song list for the album
  const prompt_varsB = {"album_name": album_name, pop_star: "Taylor Swift"};
  const formattedPromptB = await fpClient.prompts.getFormatted({
      projectId: projectID,
      templateName: "song_bot",
      environment: "latest",
      variables: prompt_varsB,
  });

  start = new Date();
  const chatCompletionB = await openai.chat.completions.create({
      messages: formattedPromptB.llmPrompt,
      model: formattedPromptB.promptInfo.model,
    	...formattedPrompt.promptInfo.modelParameters
  });
  end = new Date();

  // record to freeplay
  fpClient.recordings.create({
  		projectId,
      allMessages: formattedPromptB.allMessages({
          role: chatCompletionB.choices[0].message.role,
          content: chatCompletionB.choices[0].message.content,
      }),
      inputs: prompt_varsB,
      sessionInfo: getSessionInfo(session), // tie the completion to the session
      promptVersionInfo: formattedPromptB.promptInfo,
      callInfo: getCallInfo(formattedPromptB.promptInfo, start, end)
  });
  ```

  ```python Python theme={null}
  import os
  import time
  from freeplay import Freeplay, CallInfo, RecordPayload
  from openai import OpenAI

  #######################
  # Setup #
  #######################

  # TODO: Use environment variables in production
  project_id = os.environ.get("FREEPLAY_PROJECT_ID")
  freeplay_api_key = os.environ.get("FREEPLAY_API_KEY")
  freeplay_url = os.environ.get("FREEPLAY_URL")
  openai_api_key = os.environ.get("OPENAI_API_KEY")

  # Initialize clients
  openai = OpenAI(api_key=openai_api_key)
  fp_client = Freeplay(
      freeplay_api_key=freeplay_api_key,
      api_base="https://app.freeplay.ai/api"
  )

  ###########################
  # Create Freeplay Session #
  ###########################

  # Create a session to group related LLM calls
  # This allows tracking the entire chain as a single conversation
  session = fp_client.sessions.create()

  ##################################
  # Step 1: Call the first prompt  #
  ##################################

  # Define variables for the first prompt
  prompt_vars_a = {"pop_star": "Taylor Swift"}

  # Get formatted prompt from Freeplay
  formatted_prompt_a = fp_client.prompts.get_formatted(
      project_id=project_id,          # Freeplay project id
      template_name="album_bot",      # Name of the prompt template
      environment="latest",           # Version tag of the prompt to use
      variables=prompt_vars_a         # Variables to populate the template
  )

  # Execute LLM call with OpenAI
  start = time.time()
  chat_completion_a = openai.chat.completions.create(
      messages=formatted_prompt_a.llm_prompt,
      model=formatted_prompt_a.prompt_info.model,
      **formatted_prompt_a.prompt_info.model_parameters
  )
  end = time.time()

  # Extract the generated results for use in next step
  album_name = chat_completion_a.choices[0].message.content

  # Record the completion details back to Freeplay
  fp_client.recordings.create(
      RecordPayload(
          # Include both the original messages and the model's response
          all_messages=formatted_prompt_a.all_messages(
              new_message={
                  "role": chat_completion_a.choices[0].message.role,
                  "content": chat_completion_a.choices[0].message.content
              }
          ),
          inputs=prompt_vars_a,                               # Variables used in the prompt
          session_info=session.session_info,                  # Link to the chain session
          prompt_info=formatted_prompt_a.prompt_info,         # Prompt metadata
          call_info=CallInfo.from_prompt_info(                # Timing and performance data
              formatted_prompt_a.prompt_info, start, end
          )
      )
  )

  #############################################
  # Step 2: Call the next prompt in the chain #
  #############################################

  # Use the album name from step 1 as input for step 2
  prompt_vars_b = {
      "album_name": album_name,
      "pop_star": "Taylor Swift"
  }

  # Get formatted prompt for song generation
  formatted_prompt_b = fp_client.prompts.get_formatted(
      project_id=project_id,
      template_name="song_bot",
      environment="latest",
      variables=prompt_vars_b
  )

  # Execute second LLM call
  start = time.time()
  chat_completion_b = openai.chat.completions.create(
      messages=formatted_prompt_b.llm_prompt,
      model=formatted_prompt_b.prompt_info.model,
      **formatted_prompt_b.prompt_info.model_parameters
  )
  end = time.time()

  # Record the second completion to Freeplay
  fp_client.recordings.create(
    RecordPayload(
  				project_id=project_id,
          all_messages=formatted_prompt_b.all_messages(
              new_message={
                  "role": chat_completion_b.choices[0].message.role,
                  "content": chat_completion_b.choices[0].message.content
              }
          ),
          inputs=prompt_vars_b,
          session_info=session.session_info,                  # Same session as first call
          prompt_version_info=formatted_prompt_b.prompt_info,         
          call_info=CallInfo.from_prompt_info(
              formatted_prompt_b.prompt_info, start, end
          )
      )
  )
  ```
</CodeGroup>
