Skip to main content
AgentMark groups your OpenTelemetry traces by session, user, tags, and custom metadata. A small wrapper stores the grouping in the OpenTelemetry context, and a span processor stamps it onto every span in scope. In TypeScript this is the @agentmark-ai/otel package (withAgentMark + AgentMarkSpanProcessor); in Python it’s built into agentmark-sdk (with_agentmark, registered automatically by init_tracing). Reach for it when you instrument with OpenTelemetry rather than the AgentMark SDK’s span() helpers. It’s the recommended way to group traces on the Vercel AI SDK v7, where the telemetry.metadata option no longer reaches spans. It also groups any other OpenTelemetry span in the same scope, such as an OpenInference instrumentor, an HTTP request, or a custom span.

TypeScript

1

Install the package

npm install @agentmark-ai/otel @opentelemetry/sdk-trace-node
2

Register the span processor

Add AgentMarkSpanProcessor to your OpenTelemetry setup with your API key and app id from project settings. The register() call installs the context manager that carries grouping across await.
// instrumentation.ts
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { AgentMarkSpanProcessor } from "@agentmark-ai/otel";

const provider = new NodeTracerProvider({
  spanProcessors: [
    new AgentMarkSpanProcessor({
      apiKey: process.env.AGENTMARK_API_KEY!, // raw key, no "Bearer" prefix
      appId: process.env.AGENTMARK_APP_ID!,
    }),
  ],
});

provider.register();
3

Wrap your calls

Pass session, user, tags, and metadata to withAgentMark. Every span created inside the callback carries them.
import { withAgentMark } from "@agentmark-ai/otel";
import { generateText } from "ai";

await withAgentMark(
  {
    sessionId: "session-456",
    userId: "user-123",
    tags: ["production"],
    metadata: { feature: "support-chat" },
  },
  () => generateText({ model, prompt: "How do I reset my password?" }),
);

Python

Python grouping lives in the agentmark-sdk package. init_tracing() registers the grouping processor for you, so you only wrap your calls. Install the package:
pip install agentmark-sdk
Initialize tracing once at startup with your API key and app id from project settings:
from agentmark_sdk import AgentMarkSDK

sdk = AgentMarkSDK(api_key="...", app_id="...")
sdk.init_tracing()
Then wrap your calls with with_agentmark(...). Every span started inside it (sync or async) carries the grouping:
from agentmark_sdk import with_agentmark

with with_agentmark(
    session_id="session-456",
    user_id="user-123",
    tags=["production"],
    metadata={"feature": "support-chat"},
):
    # your OpenTelemetry-instrumented calls (OpenInference, etc.)
    ...

What gets grouped

withAgentMark accepts these fields:
  • sessionId and sessionName: group related calls into one session.
  • userId: attribute the trace to a user.
  • traceName: name the trace.
  • tags: string labels for filtering and search.
  • metadata: any custom key and value pairs, surfaced as trace metadata.
The processor stamps these onto every span in the wrapped scope, so the whole trace groups together, not only the model calls. The Python with_agentmark takes the same fields in snake_case: session_id, session_name, user_id, trace_name, tags, and metadata.
withAgentMark needs an OpenTelemetry context manager so the grouping propagates across await. Both NodeTracerProvider.register() and @vercel/otel register one.

Have questions?

Reach out any time: