ConstReadonlybotId: "bot.id"ReadonlyproviderId: "bot.provider.id"ReadonlyeventKind: "bot.event.kind"ReadonlymessageType: "bot.message.type"ReadonlychatKind: "bot.chat.kind"ReadonlychatId: "bot.chat.id"ReadonlysenderId: "bot.sender.id"ReadonlymessageId: "bot.message.id"ReadonlyinboundOutcome: "bot.inbound.outcome"ReadonlyqueueWaitMs: "bot.queue.wait_ms"ReadonlydispatchStage: "bot.dispatch.stage"ReadonlyhandlerStage: "bot.handler.stage"ReadonlymatcherKind: "bot.matcher.kind"ReadonlycommandName: "bot.command.name"ReadonlyflowId: "bot.flow.id"ReadonlyconversationId: "bot.conversation.id"ReadonlyconversationName: "bot.conversation.name"ReadonlyconversationReason: "bot.conversation.reason"ReadonlyconversationOutcome: "bot.conversation.outcome"ReadonlyconversationParked: "bot.conversation.parked"ReadonlyconversationGoto: "bot.conversation.goto"ReadonlytriggerName: "bot.trigger.name"ReadonlytriggerResult: "bot.trigger.result"ReadonlybroadcastRecipients: "bot.broadcast.recipients"ReadonlypaceMs: "bot.pace.ms"ReadonlycontentKind: "bot.content.kind"ReadonlysendOrigin: "bot.send.origin"ReadonlysendOutcome: "bot.send.outcome"ReadonlysendEdit: "bot.send.edit"ReadonlysendStream: "bot.send.stream"ReadonlyerrorType: "error.type"ReadonlylifecycleStep: "bot.lifecycle.step"Lifecycle step (storage, transport, durability…) and what it was doing.
ReadonlylifecyclePhase: "bot.lifecycle.phase"ReadonlylinkReason: "bot.link.reason"Attribute of a span LINK: why it was linked ('resume': a checkpoint carried from another process).
ReadonlytaskId: "bot.task.id"ReadonlytaskKind: "bot.task.kind"ReadonlytaskDurable: "bot.task.durable"ReadonlytaskCron: "bot.task.cron"ReadonlytaskIntervalMs: "bot.task.interval_ms"ReadonlytaskTimeZone: "bot.task.time_zone"ReadonlytaskScheduledAt: "bot.task.scheduled_at"ReadonlytaskMissed: "bot.task.missed"ReadonlytaskFencingToken: "bot.task.fencing_token"ReadonlyschedulerRole: "bot.scheduler.role"ReadonlyschedulerOwner: "bot.scheduler.owner"ReadonlygenAiOperation: "gen_ai.operation.name"ReadonlygenAiProvider: "gen_ai.provider.name"ReadonlygenAiRequestModel: "gen_ai.request.model"ReadonlygenAiRequestMaxTokens: "gen_ai.request.max_tokens"ReadonlygenAiResponseModel: "gen_ai.response.model"ReadonlygenAiInputTokens: "gen_ai.usage.input_tokens"ReadonlygenAiOutputTokens: "gen_ai.usage.output_tokens"ReadonlygenAiFinishReasons: "gen_ai.response.finish_reasons"ReadonlygenAiToolName: "gen_ai.tool.name"ReadonlygenAiToolCallId: "gen_ai.tool.call.id"ReadonlyaiPurpose: "bot.ai.purpose"ReadonlyaiStep: "bot.ai.step"ReadonlyaiStreamed: "bot.ai.streamed"ReadonlyaiCancelled: "bot.ai.cancelled"ReadonlyaiToolOutcome: "bot.ai.tool.outcome"ReadonlyaiRagChunks: "bot.ai.rag.chunks"
Every span name and attribute key the core and
@botmesh/aiwrite, in one place (so a rename of the OpenTelemetry semantic conventions is a one-line change). Thegen_ai.*keys follow the OpenTelemetry GenAI conventions (experimental).