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

# Threads & context

> Group multi-turn conversations and attach users, sessions, and metadata

Trace-level context turns a pile of individual traces into something you can slice: conversations grouped into threads, traces attributed to users, and custom metadata for filtering. Set these once on the trace and they apply to the whole execution.

## Threads (multi-turn conversations)

When one user has a back-and-forth with your agent, each turn is its own trace. Give related turns the same **thread id** so Lemma groups them into one conversation.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { propagateAttributes, startActiveObservation } from "@langfuse/tracing";

    await startActiveObservation("support-agent", async (root) => {
      root.update({ input: userMessage });

      await propagateAttributes(
        {
          traceName: "support-agent",
          sessionId: conversationId,                     // groups turns into a thread
          metadata: { "lemma.thread_id": conversationId },
        },
        async () => {
          const answer = await runAgent(userMessage);
          root.update({ output: answer });
        },
      );
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    with langfuse.start_as_current_span(name="support-agent") as root:
        root.update(input=user_message)
        langfuse.update_current_trace(
            name="support-agent",
            session_id=conversation_id,
            metadata={"lemma.thread_id": conversation_id},
        )
        answer = run_agent(user_message)
        root.update(output=answer)
    ```
  </Tab>
</Tabs>

Use the same value across every turn in a conversation. A stable conversation/session id from your app is ideal.

## Users

Attribute a trace to the end user so you can find every trace for a given user and analyze per-user behavior.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    await propagateAttributes(
      { traceName: "support-agent", userId: user.id },
      async () => {
        /* ... */
      },
    );
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    langfuse.update_current_trace(name="support-agent", user_id=user.id)
    ```
  </Tab>
</Tabs>

## Custom metadata

Attach domain-specific fields for filtering — environment, plan tier, feature flag, tenant, request id, and so on.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    await propagateAttributes(
      {
        traceName: "support-agent",
        metadata: {
          "deployment.environment.name": process.env.NODE_ENV,
          plan: "enterprise",
          tenant_id: tenantId,
        },
      },
      async () => {
        /* ... */
      },
    );
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    langfuse.update_current_trace(
        name="support-agent",
        metadata={
            "deployment.environment.name": environment,
            "plan": "enterprise",
            "tenant_id": tenant_id,
        },
    )
    ```
  </Tab>
</Tabs>

## Reference

| Context                             | Langfuse field                                     |
| ----------------------------------- | -------------------------------------------------- |
| Agent name                          | `traceName` + `metadata["gen_ai.agent.name"]`      |
| Thread / conversation               | `sessionId` (and/or `metadata["lemma.thread_id"]`) |
| User                                | `userId`                                           |
| Environment, tenant, custom filters | `metadata`                                         |

See the [trace contract](/reference/trace-contract) for how each field is read.

## Next steps

<CardGroup cols={2}>
  <Card title="Trace contract" icon="file-check" href="/reference/trace-contract">
    The exact shape Lemma reads.
  </Card>

  <Card title="Good trace vs bad trace" icon="circle-check" href="/reference/good-vs-bad-traces">
    Conformant vs malformed traces.
  </Card>
</CardGroup>
