Telemetry
Aether supports exporting OpenTelemetry GenAI traces and metrics. Configure telemetry in the top-level telemetry section of your settings file. Telemetry is disabled by default.
{ "telemetry": { "serviceName": "aether-production", "sampleRatio": 1.0, "content": { "systemInstructions": false, "inputMessages": false, "outputMessages": false, "toolDefinitions": false, "toolCalls": false }, "traces": { "enabled": true }, "metrics": { "enabled": true }, "otlp": { "endpoint": "http://localhost:4318", "headers": { "authorization": "Bearer <token>" } } }}Aether sends OTLP over HTTP/Protobuf. Set otlp.endpoint to the collector’s base URL; Aether sends traces to /v1/traces and metrics to /v1/metrics. For providers that require signal-specific URLs, set otlp.tracesEndpoint or otlp.metricsEndpoint to override the derived URL for that signal. An endpoint is required whenever either signal is enabled (either the shared endpoint or the corresponding signal-specific override).
otlp.headers values support $VAR and ${VAR} environment variable expansion (and $$ for a literal $), so you can reference secrets such as Bearer $OTEL_TOKEN without hard-coding them. Missing variables are errors, not empty substitutions.
Settings
Section titled “Settings”| Field | Default | Description |
|---|---|---|
serviceName | "aether" | The OpenTelemetry service.name resource attribute. |
sampleRatio | 1.0 | Fraction of traces to sample, from 0.0 through 1.0. Metrics are unaffected. |
content.systemInstructions | false | Export the rendered system prompt as gen_ai.system_instructions on chat spans, with its aether.llm.system_instructions.sha256 hash. |
content.inputMessages | false | Export user input as gen_ai.input.messages on turn and chat spans, with its aether.llm.input_messages.sha256 hash. |
content.outputMessages | false | Export model responses and reasoning as gen_ai.output.messages on turn and chat spans. |
content.toolDefinitions | false | Export tool definitions as gen_ai.tool.definitions on chat spans. |
content.toolCalls | false | Export tool arguments and results as gen_ai.tool.call.arguments and gen_ai.tool.call.result on tool spans. |
traces.enabled | true | Export trace spans. |
metrics.enabled | true | Export metrics. |
otlp.endpoint | — | Base URL for the OTLP/HTTP collector. Required when traces or metrics are enabled (unless a signal-specific override is set). |
otlp.tracesEndpoint | — | Exact OTLP/HTTP trace export URL. Overrides the traces URL derived from endpoint. |
otlp.metricsEndpoint | — | Exact OTLP/HTTP metric export URL. Overrides the metrics URL derived from endpoint. |
otlp.headers | {} | HTTP headers sent with OTLP requests, such as an authorization header. Values support $VAR / ${VAR} environment variable expansion. |
Set both traces.enabled and metrics.enabled to false to keep a telemetry section without creating an exporter.
Correlating SDK runs
Section titled “Correlating SDK runs”SDK callers can either continue beneath an existing OpenTelemetry parent span or start root spans with a caller-supplied trace ID:
await using continuedSession = await AetherSession.start({ traceContext: { traceparent: "00-00112233445566778899aabbccddeeff-0123456789abcdef-01", tracestate: "vendor=value", },});
await using rootSession = await AetherSession.start({ traceContext: { traceId: "00112233445566778899aabbccddeeff", },});traceContext is a run/session launch option for AetherSession.start, runHeadless, and the lower-level ACP process API; it is not a persistent telemetry setting. Telemetry still has to be enabled above — without a telemetry section the trace context is ignored.
With traceparent, Aether treats the supplied context as a remote parent, making every invoke_agent turn span its child and preserving tracestate. The parent’s sampled flag is authoritative. With traceId, each invoke_agent span is a root span with no parent span ID, and sampleRatio controls sampling.
Values are validated when telemetry starts. traceparent must follow the W3C Trace Context format with non-zero trace and parent span IDs. traceId must contain exactly 32 lowercase hexadecimal characters and cannot be all zeros. tracestate must be a valid W3C header and is only accepted with traceparent. Invalid or mixed forms fail Aether startup rather than being silently dropped.
Privacy
Section titled “Privacy”Content capture is disabled by default. Unless you enable a content flag, Aether redacts the rendered system prompt (gen_ai.system_instructions), user input, model responses, reasoning, tool definitions, and tool arguments from telemetry. Hash attributes such as aether.llm.system_instructions.sha256 are only exported if the corresponding content field is enabled.
What Aether exports
Section titled “What Aether exports”Each agent turn produces an invoke_agent root span carrying gen_ai.agent.name, so every LLM call beneath it is attributable to the agent that made it. Its child spans describe LLM calls (chat <model>) and tool executions (execute_tool <name>), including retries and terminal errors or cancellations.
With content.systemInstructions enabled, each chat <model> span carries the final rendered system prompt as gen_ai.system_instructions plus its aether.llm.system_instructions.sha256 hash, so you can compare traces across prompt changes without reading the prompt itself. With content.inputMessages enabled, turn and chat spans also carry aether.llm.input_messages.sha256 next to gen_ai.input.messages. Backends such as PostHog surface these attributes in the raw tracing tab.
When enabled, Aether also exports these GenAI histograms:
gen_ai.client.operation.durationgen_ai.client.operation.time_to_first_chunkgen_ai.client.operation.time_per_output_chunkgen_ai.client.token.usage
For the complete schema, see the field reference.