Mimir.Event.OTel (Mimir v0.7.0)

Copy Markdown View Source

Renders a Mimir.Event as OpenTelemetry attributes. This is the one place Mimir's events meet the OpenTelemetry GenAI vocabulary.

render/1 returns %{type: String.t(), attributes: %{optional(String.t()) => term()}}. type is the domain string ("llm", "agent" or "workflow").

Conventions

The gen_ai.* attribute names follow the OpenTelemetry GenAI semantic conventions as read at open-telemetry/semantic-conventions-genai@4f85037: docs/gen-ai/gen-ai-agent-spans.md, and the gen_ai.operation.name registry in model/gen-ai/registry.yaml. The conventions have Development status. At that commit, gen_ai.operation.name takes eighteen values, grouped here for reading:

  • inference: chat, generate_content, text_completion, embeddings, retrieval, fetch_response
  • agents: create_agent, invoke_agent, plan, execute_tool
  • workflows: invoke_workflow, with the workflow named by gen_ai.workflow.name
  • memory: search_memory, create_memory, update_memory, upsert_memory, delete_memory, create_memory_store, delete_memory_store

render/1 itself sets only invoke_agent.

llm

:usage with a usage map, :tool_call with a tool map, and :reasoning render exactly what the retired Mimir.TurnEvents.GenAI builders produced: gen_ai.usage.input_tokens and gen_ai.usage.output_tokens; gen_ai.tool.name and gen_ai.tool.call.id, with the call-id key present even when the id is nil; and a bare milestone key, with no gen_ai. prefix, defaulting to "". test/support/fixtures/gen_ai_compat/ holds those shapes as captured from the old builders.

Every other llm event, :tool_result included and :usage or :tool_call without its map, exports raw with its keys stringified.

agent

Every agent event renders gen_ai.operation.name as invoke_agent, and session_id, when set, as gen_ai.conversation.id. :session_open and :session_reattach both invoke an agent that exists or is brokered for the session; create_agent describes agent creation, usually in a remote agent service, which neither event records.

:turn_start, :turn_end, :terminal and :error are moments within one invocation and have no operation name of their own. They add mimir.agent.event, holding the event type.

workflow

Workflow events render mimir.workflow.event (the event type) and, when set, mimir.workflow.id and mimir.workflow.step_id. They carry no gen_ai.* attribute. That is a choice, not a gap in the conventions, which define invoke_workflow and gen_ai.workflow.name: workflow events stay on mimir.workflow.* until an ingest consumes them, so that the emitter changes alongside a consumer it can be tested against.

mimir.path

An event with a non-empty path adds mimir.path to any domain's attributes: its frames joined with /, for example "workflow:wf_123/workflow_step:step_5/agent:sess_9". An event with an empty path renders without it.

Summary

Functions

render(ev)

@spec render(Mimir.Event.t()) :: %{
  type: String.t(),
  attributes: %{optional(String.t()) => term()}
}