Update OpenTelemetry GenAI conventions to latest - #14
Update OpenTelemetry GenAI conventions to latest#14github-actions[bot] wants to merge 4 commits into
Conversation
Add .github/workflows/meai-update-otel-genai.md (and its compiled lock)
that runs daily, plus on manual dispatch, to integrate
open-telemetry/semantic-conventions GenAI updates into
Microsoft.Extensions.AI and maintain a single draft PR until the upstream
release is published.
- Invokes the update-otel-genai-conventions skill in Plan-then-Implement
mode, comparing upstream HEAD against this repo''s main.
- Relies on the skill''s change-classification reference to classify each
upstream change as actionable-now (code/minor action on an
already-emitted item) vs deferred (constant not yet emitted, no client,
server-side, doc-only), and adds a lifecycle invariant so deferral never
collapses a run into a no-op -- deferred items still keep a maintained
draft PR open.
- Finds the workflow''s PR by content (automation + area-ai labels plus the
otel-genai-tracking state block), never by branch name, then chooses an
action from PR state plus an upstream-SHA comparison: caught-up
open/merged is a no-op; behind-open-draft does an incremental push to the
PR''s existing head branch; behind-non-draft leaves an advisory comment;
merged-but-behind and any closed-without-merge PR (caught up or behind)
start a fresh PR; a still-open prior published-version PR gets only an
advisory comment.
- Defers the PR title, target token, and full PR body (status note,
what-this-implements table, upstream-scan applicability tables, and the
otel-genai-tracking state block) to the skill''s pr-description
reference: the target is `latest` while the conventions are unreleased
and a concrete v{version} once a release/schema publishes. Fresh PRs use
a unique, run-scoped branch update-otel-genai-to-{target}-{GITHUB_RUN_ID}
so they never collide with a branch a closed PR left behind; labeled
automation and area-ai; retitles the PR when the skill''s target resolves
to a version; marks it ready for review once the upstream release is
published.
- Restricts edits to src/test/docs/samples for Microsoft.Extensions.AI via
allowed-files; commits on the checked-out HEAD without creating the PR
branch locally so patch generation diffs against the exact checkout SHA.
- No-op runs write the reason to the step summary and emit no issue,
comment, or report; failures are not reported as issues; threat
detection is disabled (the sandbox, read-only permissions, and file
allow-list already constrain the run); at most one comment is posted
per run.
- Guards execution with an if condition so it only runs on dispatch or on
the canonical (non-fork) repository, and uses the Copilot PAT pool.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-genai ref
Add an optional `upstream_ref` workflow_dispatch input to the MEAI: Update
Otel Gen-AI workflow so a manual dispatch can scan a specific ref of
open-telemetry/semantic-conventions-genai instead of the default-branch HEAD.
- Declare the input in the workflow_dispatch frontmatter (git ref -- branch,
tag, or commit SHA; optional string; empty by default).
- Wire it into Step 1 via `${{ github.event.inputs.upstream_ref }}`: a
non-empty value is scanned as the upstream ref, while an empty value (every
scheduled run, and dispatches that leave it blank) scans the default-branch
HEAD. The resolved commit SHA flows into Upstream-Scan-Ref and all
downstream SHA comparisons.
- Generalize the "upstream HEAD" wording to "scanned upstream commit/SHA"
across Steps 2, 3, and 5 and the no-op rules so the language matches an
overridable scan ref.
- Recompile the lock (gh-aw v0.80.9).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add 'document' modality for application/* MIME types in DeriveModalityFromMediaType(), aligning with the updated Modality enum in the upstream gen-ai input/output message schemas (open-telemetry/semantic-conventions-genai#142). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ai#258) Emit ChatOptions.Reasoning?.Effort as gen_ai.request.reasoning.level on chat spans. Add ReasoningLevel constant to OpenTelemetryConsts.GenAI.Request. Augment ExpectedInformationLogged_Async test with Reasoning.Effort = High and the corresponding gen_ai.request.reasoning.level assertion. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Commit pushed:
|
Incremental update — upstream scan
|
| Upstream PR | Area | Change | Action |
|---|---|---|---|
| #258 | gen-ai |
gen_ai.request.reasoning.level attribute added |
🔴 Implemented |
| #162 | gen-ai |
gen_ai.conversation.compacted + CompactionPart schema |
🟡 Deferred |
| #289 | gen-ai |
gen_ai.provider.name removed from invoke_agent internal span |
✅ Already aligned |
What was implemented
gen_ai.request.reasoning.level (#258):
- Added
ReasoningLevel = "gen_ai.request.reasoning.level"constant toOpenTelemetryConsts.GenAI.Request OpenTelemetryChatClientnow emitsChatOptions.Reasoning?.Effortasgen_ai.request.reasoning.levelwhen set (e.g.ReasoningEffort.High→"high")- Augmented
ExpectedInformationLogged_Asynctest withReasoning = new ReasoningOptions { Effort = ReasoningEffort.High }and assertion for"high"
What was deferred
gen_ai.conversation.compacted + CompactionPart (#162): MEAI has no IsCompacted property on ChatOptions/ChatResponse and no CompactionContent type — both items deferred until MEAI adds compaction support.
Validation
Build clean (net8.0/net9.0/net10.0, 0 warnings). 15 OpenTelemetryChatClientTests pass across all target frameworks.
Generated by MEAI: Update Otel Gen-AI · 283.8 AIC · ⊞ 10.7K · ◷
Incremental scan update —
|
| Upstream PR | Area | Change | Applicability | Rationale |
|---|---|---|---|---|
| #179 | gen-ai |
gen_ai.prompt.version / gen_ai.prompt.variable added |
🟢 | No MEAI ChatOptions or IChatClient API exposes prompt name, version, or template variables today. Deferred until MEAI adds prompt-tracking API. |
| #201 | gen-ai |
gen_ai.invoke_agent.duration / gen_ai.execute_tool.duration metrics added |
🟡 | execute_tool.duration deferred — FunctionInvocationProcessor has no Meter/histogram infrastructure today. invoke_agent.duration — no agent framework in this repo. |
PR body updated: new rows added to the changes table and merged-upstream table; in-flight table populated with 14 open upstream PRs; Upstream-Scan-Ref advanced to 0183a25b.
Generated by MEAI: Update Otel Gen-AI · 144.9 AIC · ⊞ 10.7K · ◷
Upstream scan update — 2026-06-28Scanned upstream ref New merged changes since prior scan
Also merged between refs: dotnet#337 (pydantic-ai dep), dotnet#339 (weaver dep) — excluded (CI/deps). In-flight table updatesAdded 10 newly opened upstream PRs to the watch list: dotnet#96, dotnet#98, dotnet#143, dotnet#144, dotnet#164, dotnet#165, dotnet#184, dotnet#185, dotnet#188, dotnet#190, dotnet#195. Added dotnet#290 to the excluded list. All are 🟢 or 🟡 Watch with no current emission site in this repo. The PR body tracking block has been advanced to
|
|
Upstream scan refresh — 5 chore/deps/reference-scenario commits merged upstream since last scan (
No new Added #112 (Update dependency google-genai to v2) to the excluded CI/chore/deps list. Tracking state advanced to
|
What this PR implements
gen-aidocumentmodality forapplication/*MIME types"document"fromDeriveModalityFromMediaType()forapplication/media types. Test augmented inOpenTelemetryChatClientTests.cs.gen-aigen_ai.request.reasoning.levelChatOptions.Reasoning?.Efforton chat spans. Constant inOpenTelemetryConsts.cs. Test augmented.Validation: build clean (net8.0/net9.0/net10.0, 0 warnings); 15 tests pass. No public API change; doc-comment at
v1.41.Upstream scan tracking
Legend: 🔴 implemented here · ✅ already aligned · 🟡 watch/deferred · 🟢 not applicable (no client / docs-only)
Merged upstream changes (Unreleased) — applicability to dotnet/extensions
gen-aidocumentmodality addedDeriveModalityFromMediaType().gen-aigen_ai.request.reasoning.levelOpenTelemetryChatClient.gen-aigen_ai.invoke_agent.durationclarified as in-proc spangen-aitool.name/tool.typesampling-relevant;agent.nameonexecute_tool;agent.versionremoved frominvoke_agentStartActivitytags).agent.name: deferred.agent.versionremoval: ✅.gen-aigen-aigen_ai.prompt.version/gen_ai.prompt.variablegen-aigen_ai.invoke_agent.duration/gen_ai.execute_tool.durationmetricsFunctionInvocationProcessor, no agent framework.gen-aigen_ai.conversation.compacted+CompactionPartgen-aigen_ai.agent.namesampling-relevantgen-aiplanoperation namegen-aigen_ai.workflow.durationmetricmcpgen_ai.tool.call.arguments/.resulton MCP servergen-aigen-aigen_ai.provider.nameremoved frominvoke_agentspangen-aigen_ai.request.top_ktypedouble→intint.gen-aigen_ai.agent.idremoved from internal spansgen-aigen_ai.system_instructionslimited to textgen-aigen-aigen_ai.provider.namedescription generalizedgen-aigen_ai.provider.namerequiredness relaxedgen-aigen-aigen_ai.conversation.idpopulation guidancemcpgen-aimoonshot_aiwell-known provider valueIn-flight upstream changes (open PRs) — applicability if merged
Filter: convention-changing PRs. Excluded CI/chore/deps/reference-scenario-only: dotnet#340, dotnet#328, dotnet#325, dotnet#324, dotnet#290, dotnet#283, dotnet#112.
🟡 Watch — potential dotnet/extensions changes if merged:
gen_ai.workflow.duration→gen_ai.invoke_workflow.durationOpenTelemetryChatClienttoken metrics.gen_ai.agent.identity.id/.namegen_ai.token.cache/gen_ai.token.reasoningmetric attrsgen_ai.client.token.usage.BlobPart.contentoptional +stripped_reasonOtelMessageSerializer.byte_sizeon multimodal content partsOtelMessageSerializer.🟢 Out-of-scope (no client in this repo / server-side / docs-only):
#98,#164,#165,#184,#185,#188,#190,#195,#202,#215,#238,#250,#252,#262,#267,#270,#291,#336,#351Tracking state