Skip to main content
Sessions group related traces together, making it easier to monitor and debug complex workflows. Track entire user interactions or multi-step processes as a single unit.

What Are Sessions?

A session represents a logical grouping of traces. Common examples:
  • A conversation with a user
  • A batch processing job
  • A multi-step workflow
  • A user’s session on your application
Sessions help maintain context across multiple traces, giving you the full picture of your application’s behavior.

Creating Sessions

There are two ways to create sessions: via the trace() function (recommended for explicit tracing) or via telemetry metadata on individual prompt calls.

Using trace() with Session Options

The trace() function accepts sessionId and sessionName as first-class options:
import { trace } from "@agentmark-ai/sdk";
import { client } from "./agentmark.client";
import { generateText } from "ai";

const sessionId = `session-${Date.now()}`;

// Each trace call with the same sessionId groups under one session
const { result: greeting } = await trace(
  {
    name: 'handle-greeting',
    sessionId,
    sessionName: 'Customer Support Chat #12345',
    userId: 'user-123'
  },
  async (ctx) => {
    const prompt = await client.loadTextPrompt('chat.prompt.mdx');
    const input = await prompt.format({
      props: { message: 'Hello!' },
      telemetry: { isEnabled: true }
    });
    return await generateText(input);
  }
);

// Later, another trace in the same session
const { result: followUp } = await trace(
  {
    name: 'handle-follow-up',
    sessionId,
    sessionName: 'Customer Support Chat #12345',
    userId: 'user-123'
  },
  async (ctx) => {
    const prompt = await client.loadTextPrompt('chat.prompt.mdx');
    const input = await prompt.format({
      props: { message: 'What can you help me with?' },
      telemetry: { isEnabled: true }
    });
    return await generateText(input);
  }
);

Using Telemetry Metadata

For cases where you don’t need explicit tracing, pass session info through telemetry metadata:
import { client } from './agentmark.client';
import { generateText } from 'ai';

const sessionId = `session-${Date.now()}`;
const sessionName = 'Customer Support Chat #12345';

async function handleUserMessage(message: string) {
  const prompt = await client.loadTextPrompt('chat.prompt.mdx');

  const input = await prompt.format({
    props: { message },
    telemetry: {
      isEnabled: true,
      functionId: 'chat-handler',
      metadata: {
        userId: 'user-123',
        sessionId,
        sessionName
      }
    }
  });

  return await generateText(input);
}

// All these calls belong to the same session
await handleUserMessage('Hello!');
await handleUserMessage('What can you help me with?');
await handleUserMessage('Thanks!');

Session Patterns

Conversational Sessions

Track multi-turn conversations using trace() for full control:
import { trace } from "@agentmark-ai/sdk";
import { client } from "./agentmark.client";
import { generateText } from "ai";

class ChatSession {
  private sessionId: string;
  private sessionName: string;
  private userId: string;

  constructor(userId: string) {
    this.userId = userId;
    this.sessionId = `chat-${userId}-${Date.now()}`;
    this.sessionName = `Chat with ${userId}`;
  }

  async sendMessage(message: string) {
    const { result } = await trace(
      {
        name: 'chat-message',
        sessionId: this.sessionId,
        sessionName: this.sessionName,
        userId: this.userId
      },
      async (ctx) => {
        const prompt = await client.loadTextPrompt('chat.prompt.mdx');
        const input = await prompt.format({
          props: { message },
          telemetry: { isEnabled: true }
        });
        return await generateText(input);
      }
    );
    return await result;
  }
}

Workflow Sessions

Track multi-step workflows with child spans:
import { trace } from "@agentmark-ai/sdk";

async function processOrder(orderId: string) {
  const { result, traceId } = await trace(
    {
      name: 'process-order',
      sessionId: `order-${orderId}`,
      sessionName: `Order Processing: ${orderId}`
    },
    async (ctx) => {

      // Step 1: Validate order
      await ctx.span({ name: 'validate-order' }, async (spanCtx) => {
        const prompt = await client.loadTextPrompt('validate-order.prompt.mdx');
        const input = await prompt.format({
          props: { orderId },
          telemetry: { isEnabled: true }
        });
        await generateText(input);
      });

      // Step 2: Process payment
      await ctx.span({ name: 'process-payment' }, async (spanCtx) => {
        const prompt = await client.loadTextPrompt('process-payment.prompt.mdx');
        const input = await prompt.format({
          props: { orderId },
          telemetry: { isEnabled: true }
        });
        await generateText(input);
      });

      // Step 3: Send confirmation
      await ctx.span({ name: 'send-confirmation' }, async (spanCtx) => {
        const prompt = await client.loadTextPrompt('send-confirmation.prompt.mdx');
        const input = await prompt.format({
          props: { orderId },
          telemetry: { isEnabled: true }
        });
        await generateText(input);
      });
    }
  );
}

Batch Processing Sessions

Track batch jobs where each item generates its own trace:
import { trace } from "@agentmark-ai/sdk";

async function processBatch(items: string[]) {
  const sessionId = `batch-${Date.now()}`;
  const sessionName = `Batch Processing: ${items.length} items`;

  for (const item of items) {
    await trace(
      {
        name: 'batch-item-processor',
        sessionId,
        sessionName
      },
      async (ctx) => {
        const prompt = await client.loadTextPrompt('process-item.prompt.mdx');
        const input = await prompt.format({
          props: { item },
          telemetry: { isEnabled: true }
        });
        return await generateText(input);
      }
    );
  }
}

Session Lifecycle

Start: Create session ID when workflow begins
const sessionId = `workflow-${workflowId}-${Date.now()}`;
Use: Include in all related traces
await trace({
  name: 'step-1',
  sessionId,
  sessionName: 'My Workflow'
}, async (ctx) => { /* ... */ });
End: Session ends naturally when traces stop New Session: Create new session for new user interaction
// Don't reuse sessions across different users or workflows
const newSessionId = `session-${Date.now()}`;

Best Practices

Use consistent session IDs:
// Bad - Different IDs for same session
const sessionId = `${Math.random()}`;

// Good - Same ID throughout session
const sessionId = `session-${userId}-${Date.now()}`;
Provide descriptive names:
// Bad
sessionName: "Session 1"

// Good
sessionName: "Customer Support: Billing Issue #4532"
Include relevant context:
await trace(
  {
    name: 'support-handler',
    sessionId,
    sessionName: 'Customer Support Chat',
    userId: user.id,
    metadata: {
      userTier: user.tier,
      issueType: 'billing',
      priority: 'high'
    }
  },
  async (ctx) => {
    // ...
  }
);
Limit session scope:
// Bad - Session too broad
const sessionId = 'user-123-session'; // Used forever

// Good - Session has clear boundaries
const sessionId = `support-${ticketId}-${Date.now()}`; // One ticket

Viewing Sessions

Sessions are viewable in the AgentMark platform dashboard where you can:
  • See all traces grouped by session
  • Analyze session duration and performance
  • Filter traces within a session
  • Compare sessions
  • Debug multi-step workflows

Next Steps