> ## 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.

# Single Prompt

> Fetch a prompt from Freeplay, call an LLM, and record the completion.

### 1. Configure Freeplay Client

You'll need to set the following environment variables:

1. FREEPLAY\_API\_KEY
2. OPENAI\_API\_KEY
3. FREEPLAY\_PROJECT\_ID

### 2. Fetch Prompt

Fetch your prompt from the Freeplay server

### 3. Call your LLM

You will interact with your LLM directly, but you can key model config and messages off of the formatted prompt object

### 4. Record the LLM Interaction

Record your LLM response back to Freeplay

## Examples

<CodeGroup>
  ```python Python theme={null}
  from freeplay import Freeplay, RecordPayload, CallInfo, SessionInfo
  from openai import OpenAI

  # create your a freeplay client object
  fp_client = Freeplay(
      freeplay_api_key=os.getenv("FREEPLAY_API_KEY"),
      api_base="https://app.freeplay.ai/api"
  )
  # configure your openai client
  openai_client = OpenAI(
      api_key=userdata.get('OPENAI_API_KEY'),
  )

  project_id=os.getenv("FREEPLAY_PROJECT_ID")

  ## PROMPT FETCH ##
  # set the prompt variables
  prompt_vars = {"keyA": "valueA"}
  # get a formatted prompt
  formatted_prompt = fp_client.prompts.get_formatted(project_id=project_id,
                                                    template_name="template_name",
                                                    environment="latest",
                                                    variables=prompt_vars)

  ## LLM CALL ##
  # Make an LLM call to your provider of choice
  start = time.time()
  chat_response = openai_client.chat.completions.create(
      model=formatted_prompt.prompt_info.model,
      messages=formatted_prompt.llm_prompt,
      **formatted_prompt.prompt_info.model_parameters
  )
  end = time.time()

  # add the response to your message set
  all_messages = formatted_prompt.all_messages(
      {'role': chat_response.choices[0].message.role, 
       'content': chat_response.choices[0].message.content}
  )

  ## RECORD ##
  # create a session
  session = fp_client.sessions.create()

  # build the record payload
  payload = RecordPayload(
      project_id=project_id,
      all_messages=all_messages,
      inputs=prompt_vars,
      session_info=session, 
      prompt_version_info=formatted_prompt.prompt_info,
      call_info=CallInfo.from_prompt_info(formatted_prompt.prompt_info, start_time=start, end_time=end)
  )
  # record the LLM interaction
  fp_client.recordings.create(payload)

  ```

  ```javascript Node theme={null}
  import Freeplay, { getCallInfo, getSessionInfo } from "freeplay";
  import OpenAI from "openai";

  // create your freeplay client
  const fpClient = new Freeplay({
      freeplayApiKey: process.env["FREEPLAY_API_KEY"],
      baseUrl: "https://acme.freeplay.ai/api",
  });

  /* PROMPT FETCH */
  // set the prompt variables
  let promptVars = {"keyA": "valueA"};
  // fetch a formatted prompt template
  let formattedPrompt = await fpClient.prompts.getFormatted({
      projectId: projectID,
      templateName: "template_name",
      environment: "latest",
      variables: promptVars,
  });

  /* LLM CALL */
  // make the llm call
  const openai = new OpenAI(process.env["OPENAI_API_KEY"]);

  let start = new Date();
  const chatCompletion = await openai.chat.completions.create({
      messages: formattedPrompt.llmPrompt,
      model: formattedPrompt.promptInfo.model,
  });
  let end = new Date();
  console.log(chatCompletion.choices[0].message);

  // update the messages
  let messages = formattedPrompt.allMessages({
      role: chatCompletion.choices[0].message.role,
      content: chatCompletion.choices[0].message.content,
  });

  /* RECORD */
  // create a session
  let session = fpClient.sessions.create({});

  // record the LLM interaction with Freeplay
  await fpClient.recordings.create({
      allMessages: messages,
      inputs: promptVars,
      sessionInfo: getSessionInfo(session),
      promptVersionInfo: formattedPrompt.promptInfo,
      callInfo: getCallInfo(formattedPrompt.promptInfo, start, end)
  });
  ```

  ```java Kotlin theme={null}
  package ai.freeplay.example.kotlin

  import ai.freeplay.client.thin.Freeplay
  import ai.freeplay.client.thin.resources.prompts.ChatMessage
  import ai.freeplay.client.thin.resources.recordings.CallInfo
  import ai.freeplay.client.thin.resources.recordings.RecordInfo
  import ai.freeplay.example.java.ThinExampleUtils.callOpenAI
  import com.fasterxml.jackson.databind.ObjectMapper
  import kotlinx.coroutines.future.await
  import kotlinx.coroutines.runBlocking


  private val objectMapper = ObjectMapper()

  fun main(): Unit = runBlocking {
      // set your environment variables
      val openaiApiKey = System.getenv("OPENAI_API_KEY")
      val freeplayApiKey = System.getenv("FREEPLAY_API_KEY")
      val projectId = System.getenv("FREEPLAY_PROJECT_ID")
      val customerDomain = System.getenv("FREEPLAY_CUSTOMER_NAME")

      // create your url from your customer domain
      val baseUrl = String.format("https://%s.freeplay.ai/api", customerDomain)

      // create the freeplay client
      val fpClient = Freeplay(
              Freeplay.Config()
                      .freeplayAPIKey(freeplayApiKey)
                      .customerDomain(customerDomain)
      )

      // set the prompt variables
      val promptVars = mapOf("keyA" to "valueA")

      /* PROMPT FETCH */
      val formattedPrompt = fpClient.prompts().getFormatted<String>(
              projectId,
              "template-name",
              "latest",
              promptVars
      ).await()

      /* LLM CALL */
      // set timer to measure latency
      val startTime = System.currentTimeMillis()
      val llmResponse = callOpenAI(
              objectMapper,
              openaiApiKey,
              formattedPrompt.promptInfo.model, // get the model name
              formattedPrompt.promptInfo.modelParameters, // get the model params
              formattedPrompt.getBoundMessages()
      ).await()
      val endTime = System.currentTimeMillis()

      // add the LLM response to the message set
      val bodyNode = objectMapper.readTree(llmResponse.body())
      val role = bodyNode.path("choices").path(0).path("message").path("role").asText()
      val content = bodyNode.path("choices").path(0).path("message").path("content").asText()
      println("Completion: " + content)

      val allMessage: List<ChatMessage> = formattedPrompt.allMessages(
              ChatMessage(role, content)
      )

      /* RECORD */
      // construct the call info from the prompt object
      val callInfo = CallInfo.from(
              formattedPrompt.getPromptInfo(),
              startTime,
              endTime
      )

      // create the session and get the session info
      val sessionInfo = fpClient.sessions().create().sessionInfo

      // build the final record payload
      val recordResponse = fpClient.recordings().create(
              RecordInfo(
                      allMessage,
                      promptVars,
                      sessionInfo,
                      formattedPrompt.getPromptInfo(),
                      callInfo
              )
      ).await()
      println("Completion Record Succeeded with ${recordResponse.completionId}")

  }
  ```
</CodeGroup>
