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

# Traces

> Group completions within sessions using traces to track agent workflows.

## Using Traces

Traces are an organizing component of a session. They are used to group completions together and provide a way to track the progress of a session.

Named traces form the basis of Freeplay's support for Agents. For a comprehensive guide on building agents with traces, see [Agents](/practical-guides/agents).

| Method Name              | Parameters                                                                                                                                                                                                                                                                                                                                                                                                                        | Description                                                        |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `session.create_trace  ` | `input`: str - Input to the trace. <br />`agent_name`: str (optional) - Name of the agent/trace. <br />`parent_id`: UUID (optional) - Parent trace or completion ID for nesting. <br />`kind`: str (optional) - Either `'tool'` or `'agent'`. <br />`name`: str (optional) - Name of the trace/tool. <br />`custom_metadata`: dict\[str, Any] (optional) - Metadata to associate with the trace.                                  | Generate a TraceInfo object that will be used to group completions |
| `trace.record_output`    | `output`: str - Output of the agent/trace. <br />`project_id`: str - ID of the project to record to. <br />`eval_results`: dict\[str, Any] (optional) - Code evaluation results. <br />`test_run_info`: TestRunInfo (optional)                                                                                                                                                                                                    | Record the output to a trace                                       |
| `traces.update`          | `project_id`: str - ID of the project. <br />`session_id`: str - ID of the session. <br />`trace_id`: str - ID of the trace. <br />`output`: JSONValue (optional) - Updated output. <br />`metadata`: dict (optional) - Custom metadata. <br />`feedback`: dict (optional) - Customer feedback. <br />`eval_results`: dict (optional) - Evaluation results. <br />`test_run_info`: TestRunInfo (optional) - Test run information. | Update a trace after it has been recorded                          |

Traces are a more fine-grained way to group LLM interactions within a Session. A Trace can contain one or more completions and a Session can contain one or more Traces. Find a more detailed guide on how Sessions, Traces, and Completions fit together [here](/core-concepts/observability/sessions-traces-and-completions).

For a complete code example, see [Record Traces](/developer-resources/recipes/record-traces).

Traces are created off of an existing session object:

<CodeGroup>
  ```python python theme={null}
  input_question = "What color is the sky?"

  # create or restore a session
  session = fp_client.sessions.create()

  # create the trace
  trace_info = session.create_trace(
      input=input_question,
      agent_name="weather_agent",
      custom_metadata={
          "version": "1.0.8"
      }
  )
  ```

  ```typescript typescript theme={null}
  const inputQuestion = "Why is the sky blue?"
  // create or restore the session
  const session = await fpClient.sessions.create();

  // create the trace
  const traceInfo = await session.createTrace({
    input: inputQuestion,
    // Optional parameters
    agentName: "weather_agent",
    customMetadata: {
      version: "1.0.8"
    }
  });

  // run series of LLM completions here

  // from last llm call
  const outputAnswer = "blue"

  // record the trace
  await traceInfo.recordOutput(
    projectId,
    outputAnswer, // LLM output (string)
    // Code eval results (optional)
    {
    	sentiment: 0.7,
      validPath: true
    }
  );
  ```

  ```java java theme={null}
  String inputQuestion = "Why is the sky blue?";

  // 1. Create (or restore) a session
  FreeplayClient fpClient = new FreeplayClient("YOUR_API_KEY", "https://app.freeplay.ai/api");
  Session session = fpClient.sessions().create(projectId, "dev");  // specify environment if needed

  // 2. Start a new trace with optional agentName and metadata
  TraceInfo trace = session.createTrace(
    inputQuestion,
    "weather_agent",                     // agentName
    Map.of("version", "1.0.8")          // custom metadata
  );

  // 3. … run your LLM completions here …
  String outputAnswer = "Blue";  // final LLM answer

  // 4. Record the trace’s output along with evalResults
  trace.recordOutput(
    projectId,
    outputAnswer,
    // Eval results (optional)
    Map.of(
      "sentiment", 0.7,
      "validPath", true
    )
  );
  ```
</CodeGroup>

To tie a Completion to a given Trace you will pass the trace info in the record call

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

  # create or restore a session
  session = fp_client.sessions.create()

  # create the trace
  trace_info = session.create_trace(input=question)

  # fetch prompt
  # call LLM

  # record with trace id
  record_response = fp_client.recordings.create(
      RecordPayload(
          project_id=project_id,
          all_messages=all_messages,
          session_info=session_info,
          inputs=input_variables,
          prompt_version_info=formatted_prompt.prompt_info,
          call_info=call_info,
          trace_info=trace_info  # Pass the trace info along
      )
  )
  ```

  ```typescript typescript theme={null}
  import Freeplay, {getCallInfo, getSessionInfo} from "freeplay";

  // create or restore the session
  const session = await fpClient.sessions.create();

  // create the trace
  const traceInfo = await session.createTrace(userQuestion);

  // fetch prompt
  // call LLM

  const completionResponse = await fpClient.recordings.create(
    {
      projectId,
      allMessages: messages,
      inputs: input_variables,
      sessionInfo: session,
      promptVersionInfo: formattedPrompt.promptInfo,
      callInfo: getCallInfo(formattedPrompt.promptInfo, start, end),
      traceInfo: traceInfo // Pass the trace info
    }
  )
  ```

  ```java java theme={null}
  // create or restore a session
  Session session = fpClient.sessions().create();

  // create the trace
  TraceInfo trace = session.createTrace(inputQuestion);

  // fetch prompt
  // run llm completion

  // record with the trace id
  RecordInfo recordInfo = new RecordInfo(projectId, allMessages)
      .inputs(variables)
      .sessionInfo(sessionInfo)
      .promptVersionInfo(formattedPrompt.getPromptInfo())
      .callInfo(callInfo);
  // add the trace info
  recordInfo.traceInfo(trace);
  ```
</CodeGroup>

For a complete working example, see [Record Traces](/developer-resources/recipes/record-traces). For agent-specific patterns, see [Agents](/practical-guides/agents).

Once you have recorded completions to the trace and are on the final output, you must close your trace in order to wrap the completions together, you can also optionally record eval results to the trace at this point:

<CodeGroup>
  ```python python theme={null}
  # record output to the trace
  output_answer = "blue" # from the LLM
  trace_info.record_output(
    project_id=project_id,
    output=output_answer,
    eval_results={  # Optional trace eval logging
      "sentiment": 0.7,
      "valid_path": True,
    }
  )
  ```

  ```typescript typescript theme={null}
  import Freeplay, { getCallInfo, getSessionInfo } from "freeplay";

  // create or restore the session
  const session = await fpClient.sessions.create();

  // create the trace
  const traceInfo = await session.createTrace(userQuestion);

  // fetch prompt
  // call LLM

  const completionResponse = await fpClient.recordings.create({
    projectId,
    allMessages: messages,
    inputs: input_variables,
    sessionInfo: session,
    promptInfo: formattedPrompt.promptInfo,
    callInfo: getCallInfo(formattedPrompt.promptInfo, start, end),
    traceInfo: traceInfo, // Pass the trace info
  });
  ```

  ```java java theme={null}
  // create or restore a session
  Session session = fpClient.sessions().create();

  // create the trace
  TraceInfo trace = session.createTrace(inputQuestion);

  // fetch prompt
  // run llm completion

  // record with the trace id
  RecordInfo recordInfo = new RecordInfo(
    projectId,
    allMessages,
    variables,
    session.getSessionInfo(),
    formattedPrompt.getPromptInfo(),
    callInfo,
   );
  // add the trace info
  recordInfo.traceInfo(trace);
  ```
</CodeGroup>

### Adding Tools to Traces

When building agents that use tools, tool calls are recorded as the output of an LLM call by default. You can also add explicit tool spans to provide more data about tool execution, including latency and other metadata. These are recorded as a Trace with `kind='tool'` and linked to the parent completion using `parent_id`.

For complete examples and code snippets, see [Tool Calls](/practical-guides/tools).

### Updating a Trace

Freeplay allows you to update a trace after it has been recorded. This is useful for adding evaluation results, customer feedback, metadata, or updating the output. To do this, you need the `project_id`, `session_id`, and `trace_id`. You must provide at least one of `output`, `metadata`, `feedback`, `eval_results`, or `test_run_info`.

<CodeGroup>
  ```python python theme={null}
  from freeplay.resources.traces import TraceUpdatePayload

  # Update the trace with evaluation results and feedback
  fp_client.traces.update(
      TraceUpdatePayload(
          project_id=project_id,
          session_id=session.session_id,
          trace_id=trace_info.trace_id,
          output="updated output",
          metadata={"version": "1.0.8"},
          feedback={"freeplay_feedback": "positive", "satisfaction": True},
          eval_results={"accuracy": 0.99},
      )
  )
  ```

  ```typescript typescript theme={null}
  import { TraceUpdatePayload } from "freeplay";

  // Update the trace with evaluation results and feedback
  await fpClient.traces.update({
    projectId,
    sessionId: session.sessionId,
    traceId: traceInfo.traceId,
    output: "updated output",
    metadata: { version: "1.0.8" },
    feedback: { freeplay_feedback: "positive", satisfaction: true },
    evalResults: { accuracy: 0.99 },
  });
  ```

  ```java java theme={null}
  import ai.freeplay.client.resources.traces.TraceUpdatePayload;

  // Update the trace with evaluation results and feedback
  fpClient.traces().update(
      new TraceUpdatePayload(projectId, sessionId, String.valueOf(traceInfo.getTraceId()))
          .output("updated output")
          .metadata(Map.of("version", "1.0.8"))
          .feedback(Map.of("freeplay_feedback", "positive"))
          .evalResults(Map.of("accuracy", 0.99))
  ).get();
  ```
</CodeGroup>
