What Are Sessions?

Sessions in Laminar provide a way to group related traces together. This is particularly useful for:

  • Grouping traces from a single user interaction
  • Connecting multiple API requests that form a logical sequence
  • Organizing conversational turns in a chatbot
  • Tracking complex workflows across multiple functions or services

For example, in a conversational agent, each turn in the conversation might be represented as a trace, while the entire conversation would be a session.

Creating Sessions

You can associate a trace with a session using the following methods:

Use the Laminar.withSession wrapper function to create a context with a sessionId:

import { Laminar } from "@lmnr-ai/lmnr";

Laminar.initialize({
  projectApiKey: process.env.LMNR_PROJECT_API_KEY,
  instrumentModules: {
    // your libraries to instrument
  },
});

Laminar.withSession({ sessionId: "session123"}, () => {
  // Your code here
  // All spans created within this function will be associated with session123
});

Alternative: Setting Session ID with Observe

You can also set the session ID directly when using the observe decorator/wrapper, which is often simpler and more reliable:

import { Laminar, observe } from "@lmnr-ai/lmnr";

// Set session ID in the observe function
await observe(
  {
    name: "myFunction",
    sessionId: "session123"
  },
  async () => {
    // Function code here
  }
);

Viewing Sessions

To view sessions in the Laminar UI:

  1. Navigate to the Traces page
  2. Select the “Sessions” tab
  3. Click on a session to expand it and see all traces within that session

Each trace within a session contains the same information as a standalone trace:

Use Cases

Chatbot Conversations

For a chatbot, each user message and response can be a separate trace, with the entire conversation as a session:

# Each turn is a separate trace
@observe(session_id=conversation_id)  # Setting session ID in the decorator is preferred
def handle_turn(user_message):
    # Process message, call LLMs, etc.
    return response

# Alternatively, with manual session management:
@observe()
def handle_turn_alt(user_message, conversation_id):
    Laminar.set_session(session_id=conversation_id)  # Must be within span context
    # Process message, call LLMs, etc.
    return response

Multi-step Workflows

For complex workflows spanning multiple API calls:

// Start a session for a user's checkout process
Laminar.withSession({ sessionId: `checkout-${userId}` }, async () => {
  // Each step in the process is a separate trace
  await observe({ name: "validateCart" }, async () => { /* ... */ });
  await observe({ name: "processPayment" }, async () => { /* ... */ });
  await observe({ name: "createOrder" }, async () => { /* ... */ });
});