SWIRLS_
PlatformObservability

Attribute schema

Every attribute key on a Swirls span. Its type, the span it lives on, whether it is identity or content, and what content policy governs it.

What it is. The complete dictionary of attribute keys Swirls sets on a run's spans. Each key is listed with its type, the span it appears on, its category, and a description. Read alongside the Span spec, which defines the spans these attributes live on.

There are two namespaces.

  • swirls.* for Swirls primitives: executions, nodes, agents, sandboxes, and run identity.
  • gen_ai.* from the OpenTelemetry GenAI semantic conventions, used as-is so an exported trace renders in Datadog, Tempo, or Honeycomb without translation.

Categories

Every attribute falls into one of four categories. The category tells you whether a key is always present and whether a content policy governs it.

CategoryAlways presentDescription
IdentityYesTies a span to a tenant, project, and run. Never redacted, so a trace stays navigable.
StructureYesNames, kinds, status, and configuration. The shape and outcome of the run.
MetricWhen reportedToken counts. The numbers cost and usage roll up from.
ContentPolicy-gatedRun I/O: inputs, outputs, prompts, completions, messages, command text. Governed by the project content policy (full, redacted, off). See Content policy.

Content keys are the ones a content policy governs. Under redacted only the shape survives; under off the key is never set. Identity, Structure, and Metric attributes are unaffected by the policy.

Identity (swirls.*)

Stamped onto every span in a run from the active scope, so the whole trace tree routes to one project and execution. See Identity and scope.

KeyTypeCategoryDescription
swirls.org.idstringIdentityThe organization that owns the run.
swirls.project.idstringIdentityThe project. The key the trace store routes and filters on.
swirls.deployment.idstringIdentityThe deployment the run came from.
swirls.workflow.idstringIdentityThe workflow definition.
swirls.execution.idstringIdentityThe single run.
swirls.span.kindstringStructureStructural classification: workflow, agent, llm, tool, or internal. Stamped from the span name.

Workflow run (swirls.*)

On the swirls.graph.execution root and its node spans, set by the executor.

KeyTypeCategorySpanDescription
swirls.workflow.labelstringStructuregraph, nodeHuman-readable workflow name.
swirls.execution.statusstringStructuregraph (or root agent turn)Run outcome: completed or failed. One per trace.
swirls.parent.execution.idstringIdentitygraph, nodeThe calling execution, when this run is a nested workflow.
swirls.trigger.typestringStructuregraph, nodeWhat started the run (for example webhook, schedule, manual).
swirls.trigger.idstringIdentitygraph, nodeThe specific trigger instance.
swirls.child.execution.idstringIdentityswirls.workflow.invokeLinks to the root span of a nested workflow's own trace.

Node (swirls.*)

On the swirls.node.execution span, set by the executor.

KeyTypeCategoryDescription
swirls.node.idstringStructureThe node's id within the workflow.
swirls.node.namestringStructureThe node's name.
swirls.node.inputJSON stringContentThe node's input payload.
swirls.node.outputJSON stringContentThe node's output payload.
swirls.node.metaJSON stringContentOperation metadata the node returned (HTTP status, scrape credits, parallel counts, and similar).
swirls.ai.promptJSON stringContentThe prompt an ai node sent to the model, separable from node input.
swirls.ai.responseJSON stringContentThe response an ai node received, separable from node output.
swirls.agent.messagesJSON stringContentThe accumulated transcript of an agent node, stamped when the node ends.

Agent turn (swirls.*)

On the gen_ai.invoke_agent span, set by the agent host. The content keys are captured only when a content policy is resolved (the chat and API paths); the executor agent-node path captures the transcript through swirls.agent.messages instead.

KeyTypeCategoryDescription
swirls.session.idstringIdentityThe session for a chat or API agent call.
swirls.sandbox.keystringIdentityThe sandbox backing the turn.
swirls.agent.disk.gibnumberStructureConfigured disk allocation, in GiB.
swirls.agent.max_stepsnumberStructureConfigured maximum tool-loop iterations.
swirls.agent.output_modestringStructureHow the turn produces output: text, object, or submit_tool.
swirls.agent.tool_namesstring[]StructureThe tools made available to the turn.
swirls.agent.prior_message_countnumberStructureLength of the message history fed into the turn.
swirls.agent.step_countnumberStructureTool-loop steps actually run.
swirls.agent.tool_call_countnumberStructureTotal tool calls the model made across the turn.
swirls.agent.structured_output.repair_countnumberStructureTimes structured output was repaired before validating.
swirls.agent.user_messageJSON stringContentThe user message that drove the turn.
swirls.agent.response_messageJSON stringContentThe final agent response.
swirls.llm.system_promptJSON stringContentThe system prompt sent to the model.
swirls.llm.input_messagesJSON stringContentThe full transcript sent to the model (prior turns plus this message).
swirls.llm.output_messagesJSON stringContentThe full response transcript from the model.
swirls.llm.tool_callsJSON stringContentValid tool calls the model made.
swirls.llm.invalid_tool_callsJSON stringContentMalformed or non-existent tool calls the model attempted.
swirls.llm.toolsJSON stringContentThe tool definitions made available to the model.

Sandbox and tools (swirls.*)

On the swirls.sandbox.exec span, set by the agent host.

KeyTypeCategoryDescription
swirls.sandbox.programstringStructureThe program or command name run in the sandbox.
swirls.sandbox.exit_codenumberStructureThe process exit code.
swirls.tool.namestringStructureThe tool a span executed.
swirls.sandbox.commandJSON stringContentThe full command text with arguments. Can carry secrets, so it is policy-gated.

Sentinel (swirls.*)

KeyTypeCategoryDescription
swirls.trace.completebooleanStructureSet to true on the per-trace completion sentinel span. Marks the trace tree finished.

GenAI semantic conventions (gen_ai.*)

OpenTelemetry GenAI keys, set on agent turn, model call, and tool spans. Token usage is the headline cost metric and is stamped wherever a provider reports it.

KeyTypeCategoryDescription
gen_ai.operation.namestringStructureOperation: create_agent, invoke_agent, chat, or execute_tool.
gen_ai.agent.namestringStructureThe agent's display name.
gen_ai.systemstringStructureThe model provider (for example anthropic, openai).
gen_ai.request.modelstringStructureThe model id sent in the request.
gen_ai.response.modelstringStructureThe model id that answered, which can differ when routed.
gen_ai.response.finish_reasonsstring[]StructureWhy the model stopped (for example stop, length, tool_call).
gen_ai.tool.namestringStructureThe tool name on a tool-call span.
gen_ai.tool.call.idstringStructureThe unique id of a tool invocation.
gen_ai.usage.input_tokensnumberMetricPrompt tokens consumed.
gen_ai.usage.output_tokensnumberMetricCompletion tokens generated.
gen_ai.usage.total_tokensnumberMetricInput plus output tokens.
gen_ai.usage.reasoning_tokensnumberMetricExtended-thinking tokens, where the provider reports them.
gen_ai.usage.cached_input_tokensnumberMetricPrompt tokens read from the provider's prompt cache.
gen_ai.usage.cache_creation_input_tokensnumberMetricPrompt tokens written to the provider's prompt cache.
gen_ai.input.messagesJSON stringContentMessages sent to the model. Emitted by the AI SDK on per-call spans. See note below.
gen_ai.output.messagesJSON stringContentMessages returned by the model. Emitted by the AI SDK on per-call spans. See note below.

gen_ai.input.messages and gen_ai.output.messages are emitted by the AI SDK on its per-call model spans and ride a default-off path that the collector strips, so they do not persist. Durable, policy-gated message capture happens on the owning agent turn span through swirls.llm.input_messages and swirls.llm.output_messages.

Reserved keys

These keys are defined in the schema but are not currently emitted onto customer-facing spans. They are reserved so that adding them later is one change, not a rename. Do not depend on them in queries or exports yet.

KeyIntended use
swirls.node.typeThe node's type (for example agent, http, code).
swirls.sandbox.idA stable sandbox identifier, distinct from the per-turn swirls.sandbox.key.
swirls.agent.wallet.reserved_centsReserved token budget for an agent turn, in cents.
swirls.agent.wallet.settled_centsSettled token spend for an agent turn, in cents.
swirls.agent.wallet.window_keyThe billing window an agent turn settled against.
swirls.agent.zero_run_idCorrelation id for the agent run.
swirls.agent.disk.external_idThe external volume id for an agent's disk.

Redaction on export

When you export traces to a destination set to redacted, the Content keys above are stripped from the exported spans while Identity, Structure, and Metric keys are kept, so the exported trace stays navigable. The export denylist and the capture gate are kept together in the codebase, so a new content attribute is redacted on export by the same change that adds it.

On this page