SpanOptions field. To wire any of this into your application, see Set up tracing.
Collected spans
AgentMark classifies every ingested OpenTelemetry span by type:
The spans API accepts a third type,
EVENT, for point-in-time records.
Span attributes
Each span carries detailed attributes: Model information:ai.model.id (for example, "gpt-5-mini"), ai.model.provider (for example, "openai")
Token usage: gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, gen_ai.usage.total_tokens (the ai.usage.promptTokens / ai.usage.completionTokens aliases are also accepted)
Telemetry metadata: ai.telemetry.functionId, ai.telemetry.metadata.*
Response details: ai.response.text, ai.response.toolCalls, ai.response.finishReason
Prompt identity and version linking
AgentMark links each prompt run to the exact prompt version, not just the prompt name:agentmark.prompt_name: the prompt’s frontmattername. Both the TypeScript and Python SDKs emit this attribute on the prompt-run span; it powers the prompt label column on the trace surfaces.agentmark.metadata.commit_sha: the git commit the prompt content was served at. When you load a prompt from AgentMark Cloud, the gateway stamps the served-at commit into the prompt’sagentmark_meta.commit_sha(the pinned environment commit for keys bound to a pinned environment, the latest synced commit otherwise). The local CLI dev server stamps your repo’sHEADthe same way. The SDK’s run path echoes that commit onto the trace automatically, with no code change needed.
CommitSha always reflects the server’s recorded deployment, so a client can never claim an arbitrary commit.
Trace-level input and output
The trace list and trace detail views show a single input/output per trace. AgentMark derives these from spans at read time, identically in AgentMark Cloud and the local dev server’sGET /v1/traces/:id:
- Root span first. The prompt-run (root) span’s
agentmark.input/agentmark.outputattributes win when present. The WebhookRunner records these automatically on every run: the formatted messages as input right after the prompt renders, and the final text/object as output when the event stream drains, in both streaming and non-streaming modes. - GENERATION fallback. When the root span carries no I/O (third-party OTEL instrumentation pointed straight at the collector), AgentMark uses the first GENERATION span’s input and the last GENERATION span’s output instead, in timestamp order.
- Executors never set trace I/O. If
agentmark doctor --smoke(the CLI’s instrumentation smoke test) reports a trace missing input/output, the fix is in instrumentation, not in your executor. - GENERATION spans come from your model SDK’s instrumentation, for example
experimental_telemetrywith the Vercel AI SDK, orAgent.instrument_all(InstrumentationSettings(version=3))with Pydantic AI.
SpanOptions
SpanOptions configure a span created with span() / span_context(). To set them up in code, see Grouping operations into a span.
The option names above are TypeScript. Python’s
SpanOptions uses the snake_case equivalents: user_id, session_id, session_name, prompt_name, dataset_run_id, and so on.observe() options
observe() wraps an async function with automatic input/output capture and lets you set a SpanKind. For the call patterns, see Wrapping functions with observe().
SpanKind values
SpanKind sets the semantic kind of a span, which drives how you filter spans and how dashboards group them.
SpanResult
span() returns a SpanResult in TypeScript:
span_context() is an async context manager that exposes trace_id on the context object:
Have questions?
Reach out any time:
- Email the team at hello@agentmark.co for support
- Schedule an Enterprise Demo to learn about AgentMark’s business solutions