Skip to content

fix(otel): eliminate gen_ai.usage.* double-counting and gen_ai.request.model duplicate on agent span#30350

Merged
pelikhan merged 3 commits into
mainfrom
copilot/remove-duplicate-token-attributes
May 5, 2026
Merged

fix(otel): eliminate gen_ai.usage.* double-counting and gen_ai.request.model duplicate on agent span#30350
pelikhan merged 3 commits into
mainfrom
copilot/remove-duplicate-token-attributes

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 5, 2026

gen_ai.usage.* token attributes were being added to the shared attributes array before agentAttributes = [...attributes] was constructed, landing the same four token counters on both gh-aw.agent.conclusion and gh-aw.agent.agent spans. Any backend summing these across a trace returned 2× actual token counts. Additionally, gen_ai.request.model was pushed to attributes early then pushed again explicitly into agentAttributes, producing a duplicate key on the agent span.

Changes

  • send_otlp_span.cjs

    • Collect gen_ai.usage.* attrs into a local usageAttrs array instead of pushing directly into attributes
    • When an agent sub-span is emitted: spread usageAttrs into agentAttributes only — conclusion span gets none
    • When no agent sub-span is emitted: push usageAttrs into attributes (conclusion span) so single-span observability is preserved without a join
    • Remove the redundant gen_ai.request.model push into agentAttributes (already present via the [...attributes] spread)
  • send_otlp_span.test.cjs

    • Update conclusion-span token tests to assert the four gen_ai.usage.* keys are absent when an agent sub-span is emitted
    • Add test asserting gen_ai.request.model appears exactly once on the agent span
// Before: token attrs pushed to shared array → copied to both spans
attributes.push(buildAttr("gen_ai.usage.input_tokens", agentUsage.input_tokens));
// ...
const agentAttributes = [...attributes]; // ← double-counted

// After: isolated in usageAttrs, merged only into agentAttributes
const usageAttrs = [];
usageAttrs.push(buildAttr("gen_ai.usage.input_tokens", agentUsage.input_tokens));
// ...
const agentAttributes = [...attributes, ...usageAttrs]; // agent span only
// if no agent span: attributes.push(...usageAttrs)    // conclusion span only

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh gh repo view --json owner,name --jq .owner.login + "/" + .name k (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw bagabas/go-udiffinit --end-of-options ache/go/1.25.8/x64/pkg/tool/linuremote.origin.url sRem�� SvuWvV_iU **/*.cjs ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet **/*.json --ignore-path ../../../.pretti--show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw er_test pkg/workflow/clauser.name ache/go/1.25.8/xTest User (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name on' --ignore-patgo1.25.8 (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv /ref/tags/v9 /opt/hostedtoolc--jq sv -bool -buildtags /tmp/go-build380--show-toplevel git rev-�� --show-toplevel /tmp/go-build3801829731/b421/fileutil.test /usr/bin/git -test.paniconexigh -test.v=true /usr/lib/git-cor/repos/actions/github-script/git/ref/tags/v9 git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv --show-toplevel x_amd64/compile er: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabl--show-toplevel --local .cfg 64/pkg/tool/linu/repos/actions/github-script/git/ref/tags/v9 git conf�� user.name Test User /usr/bin/git ude_logs.go .cfg tartedAt,updated--show-toplevel /usr/bin/git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv -unreachable=false /tmp/go-build3801829731/b143/vet.cfg e/git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel infocmp /usr/bin/git BHBh/Mm0ui0x2Iv4git -tests /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel node /usr/bin/git /tmp/TestHashCongit 1829731/b460/_terev-parse /usr/bin/infocmp--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv k/_tool infocmp /usr/bin/infocmp tags/v6 64/pkg/tool/linurev-parse sv infocmp -1 xterm-color infocmp /home/REDACTED/.local/bin/node xterm-color /opt/hostedtoolcrev-parse /usr/bin/infocmp--show-toplevel node (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv runs/20260505-125135-14164/test-3056747236 --jq (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv -bool l /opt/hostedtoolcache/node/24.14.1/x64/bin/node -errorsas -ifaceassert -nilfunc node /tmp�� /tmp/TestHashStability_SameInputSameOutput287149578/001/stability-test.md -tests /usr/bin/git actions/setup/jsgit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv --show-toplevel x_amd64/vet /usr/bin/git --get-regexp --local x_amd64/vet git remo�� (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv /repos/actions/setup-node/git/ref/tags/v4 --jq /usr/bin/git /ref/tags/v9 remote.origin.urrev-parse sv git rev-�� --show-toplevel git /usr/bin/git /tmp/gh-aw-test-git resolved$ (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv /send_otlp_span.test.cjs (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv path .prettierig-errorsas (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9.0.0
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv /send_otlp_span.test.cjs (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9.0.0 --jq [.object.sha, .object.type] | @tsv -c=4 -nolocalimports -importcfg /tmp/go-build3801829731/b398/importcfg -embedcfg /tmp/go-build3801829731/b398/embedcfg -pack (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel /opt/hostedtoolc--jq /usr/bin/git SameOutput287149git /tmp/go-build380rev-parse e/git-upload-pac--show-toplevel git rev-�� --show-toplevel /opt/hostedtoolc--jq /usr/bin/git -unreachable=falgit /tmp/go-build380rev-parse ache/node/24.14.--show-toplevel git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /ref/tags/v9 remote.origin.url sv -c=4 -nolocalimports -importcfg git -C /tmp/gh-aw-test-runs/20260505-125135-14164/test-4139448571 resolved$ (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /ref/tags/v9 64/pkg/tool/linuconfig sv 4139448571 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv ithub-script/git/ref/tags/v9 ache/node/24.14.1/x64/bin/node bject.type] | @tsv ue.number (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv xterm-color -tests t k/_temp/copilot-infocmp (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv /tmp/gh-aw-test-runs/20260505-125135-14164/test-2389925063/.github/workflows config /usr/bin/git remote.origin.urgit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv ansitiveImports3822226293/001 x_amd64/vet /usr/bin/git --get-regexp --local x_amd64/vet git conf�� --get remote.origin.url /usr/bin/git 991165933/001 991165933/002/worev-parse x_amd64/vet git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq /usr/bin/git */*.ts' '**/*.jsgit --local x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git b/workflows --local x_amd64/compile git (http block)
  • https://api.github.com/repos/aws-actions/configure-aws-credentials/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/aws-actions/configure-aws-credentials/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git ons-test29275456git config /usr/bin/git git rev-�� --show-toplevel git /usr/bin/gh /tmp/gh-aw-test-gh l /opt/hostedtoolcstatus gh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/aws-actions/configure-aws-credentials/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/node/24.14.1/x64/bin/node /usr/bin/git /tmp/TestGuardPogh config /usr/bin/git git rev-�� /ref/tags/v9 git sv mpleWorkflow2644git x_amd64/vet om/upstream/repo--show-toplevel gh (http block)
  • https://api.github.com/repos/azure/login/git/ref/tags/v2
    • Triggering command: /usr/bin/gh gh api /repos/azure/login/git/ref/tags/v2 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git --show-toplevel /home/REDACTED/worrev-parse /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linuowner/host-repo /usr/bin/infocmp -bool l /usr/bin/git infocmp (http block)
  • https://api.github.com/repos/docker/login-action/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/docker/login-action/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv --show-toplevel node /usr/bin/git /tmp/TestHashCongit 1829731/b460/_terev-parse /usr/bin/infocmp--show-toplevel git rev-�� --show-toplevel infocmp /usr/bin/git xterm-color x_amd64/vet ipts.test git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/go/1.25.8/x64/pkg/tool/linux_amd64/link /usr/bin/git vaScript36988311infocmp -trimpath e/git git rev-�� --show-toplevel e/git /usr/bin/git ithub/workflows -buildtags 1/x64/bin/node git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv --show-toplevel 02zfbN4/uSkbk2BocNu6uh6Xsdg3 /usr/bin/git it} --local x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git ions-build/main.git credential.helperev-parse x_amd64/vet git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: `/usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @TSV user.name Test User /opt/hostedtoolcache/node/24.14.1/x64/bin/node it} --local x_amd64/vet /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� 'full-sweep (enforce_all)' x_amd64/vet /usr/bin/git ub/workflows n

Agent-Logs-Urrev-parse 64/pkg/tool/linu--show-toplevel git` (http block)

  • https://api.github.com/repos/github/gh-aw/actions/runs
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created >=2026-04-28 (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created >=2026-04-05 (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --limit 100 --created >=2026-02-04 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name on ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /../../.prettier/usr/bin/git erignore (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 .cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name om/stretchr/[email protected]/require/forward_requgithub.com/github/gh-aw/pkg/cli_test x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 on eutil.test /../../.prettier/opt/hostedtoolcache/node/24.14.1/x64/bin/node erignore (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1234567890
    • Triggering command: /usr/bin/gh gh api repos/{owner}/{repo}/actions/runs/1234567890 --jq {databaseId: .id, number: .run_number, url: .html_url, status: .status, conclusion: .conclusion, workflowName: .name, workflowPath: .path, createdAt: .created_at, startedAt: .run_started_at, updatedAt: .updated_at, event: .event, headBranch: .head_branch, (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name on x_amd64/link (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 on ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /../../.prettier/usr/bin/git erignore ACCEPT ache/go/1.25.8/x64/pkg/tool/linu--jq (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name .cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /../../.prettiergit erignore (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 .cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/link (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name .cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /../../.prettier/usr/bin/git erignore (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 .cfg ache/go/1.25.8/x64/pkg/tool/linu-lang=go1.25 (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name on ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /../../.prettier/opt/hostedtoolcache/node/24.14.1/x64/bin/node erignore (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 stmain.go x_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name on 64/pkg/tool/linux_amd64/vet /../../.prettiergit erignore (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 1829731/b006/vet.cfg x_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path on' --ignore-path ../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 (http block)
  • https://api.github.com/repos/github/gh-aw/contents/.github/workflows/shared/reporting.md
    • Triggering command: /tmp/go-build3801829731/b404/cli.test /tmp/go-build3801829731/b404/cli.test -test.testlogfile=/tmp/go-build3801829731/b404/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv --show-toplevel node (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv 1505809659/001 sRemoteWithRealGitmaster_branch1449778002/002/work g_.a **/*.json --ignore-path ../../../.prettixterm-color ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -c "prettier" --write '../../../**/*.json' '!../../remote.origin.url (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv 3581593162/.github/workflows --local x_amd64/vet credential.userngit (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv */*.ts' '**/*.json' --ignore-path ../../../.pret.prettierignore --local x_amd64/vet user.name (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv */*.ts' '**/*.json' --ignore-path ../../../.prettierignore --local x_amd64/vet user.name (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv */*.ts' '**/*.json' --ignore-path ../../../.prettierignore --local x_amd64/vet user.email (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv */*.ts' '**/*.json' --ignore-path ../../../.pret.prettierignore --local x_amd64/vet =fetch (http block)
  • https://api.github.com/repos/google-github-actions/auth/git/ref/tags/v2
    • Triggering command: /usr/bin/gh gh api /repos/google-github-actions/auth/git/ref/tags/v2 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git /tmp/TestGuardPogit remote /usr/bin/gh git rev-�� --show-toplevel gh /usr/bin/git res_import_test.git t_schema_test.gorev-parse 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv --write **/*.cjs ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet **/*.json --ignore-path run-script/lib/n--get-regexp ache/go/1.25.8/x^remote\..*\.gh-resolved$ -c 5135-14164/test-2306341859/.github/workflows (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion ./../.prettieriggit (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo ode_modules/.bin/sh (http block)
    • Triggering command: /usr/bin/gh gh workflow list --repo owner/repo --json name,path,state .cfg **/*.ts **/*.json --ignore-path ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name on' --ignore-path ../../../.prettierignore (http block)
  • https://api.github.com/repos/test/repo
    • Triggering command: /usr/bin/gh gh api /repos/test/repo --jq .default_branch t4083530751 1829731/b101/vet.cfg .yml (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI and others added 2 commits May 5, 2026 12:48
… spans

- Move gen_ai.usage.* token-count attributes to a separate usageAttrs array
  instead of pushing directly into the shared attributes (conclusion span) array.
  When an agent sub-span is emitted, usageAttrs are added exclusively to
  agentAttributes so the token counts appear only on the gh-aw.agent.agent span.
  When no agent span is emitted (non-agent jobs), usageAttrs fall through to the
  conclusion span so observability requires no extra join.
- Remove the duplicate push of gen_ai.request.model to agentAttributes at
  line 1285; the attribute is already present via the [...attributes] spread.
- Update conclusion-span tests to assert that token attrs are absent when an
  agent sub-span is emitted (they now live on the agent span only).
- Add test verifying gen_ai.request.model appears exactly once on the agent span.

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/dd0c61dc-f073-4e18-a47a-0d77006c19e1

Co-authored-by: pelikhan <[email protected]>
Copilot AI changed the title [WIP] Improve OTel instrumentation by removing duplicate token attributes fix(otel): eliminate gen_ai.usage.* double-counting and gen_ai.request.model duplicate on agent span May 5, 2026
Copilot AI requested a review from pelikhan May 5, 2026 12:55
@pelikhan pelikhan marked this pull request as ready for review May 5, 2026 12:56
Copilot AI review requested due to automatic review settings May 5, 2026 12:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes OpenTelemetry GenAI attribute duplication by ensuring gen_ai.usage.* token counters are only attached to the dedicated agent span (when emitted), and by preventing gen_ai.request.model from being added twice to the agent span.

Changes:

  • Refactors token-usage attribute construction to avoid double-counting across conclusion + agent spans.
  • Removes a redundant gen_ai.request.model push that produced duplicate keys on the agent span.
  • Updates/adds tests to assert token attributes are absent from the conclusion span when an agent sub-span is emitted, and that gen_ai.request.model appears exactly once on the agent span.
Show a summary per file
File Description
actions/setup/js/send_otlp_span.cjs Isolates gen_ai.usage.* into usageAttrs and attaches them only to the agent span when present; removes duplicate gen_ai.request.model push.
actions/setup/js/send_otlp_span.test.cjs Updates assertions to prevent regression on token double-counting and model-key duplication.
.github/workflows/stale-pr-cleanup.lock.yml Updates pinned firewall/AWF image/version references (auto-generated lockfile change).

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 1

Comment on lines 112 to 116
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
GH_AW_INFO_AWF_VERSION: "v0.25.38"
GH_AW_INFO_AWF_VERSION: "v0.25.39"
GH_AW_INFO_AWMG_VERSION: ""
@pelikhan pelikhan merged commit d6ae06d into main May 5, 2026
4 checks passed
@pelikhan pelikhan deleted the copilot/remove-duplicate-token-attributes branch May 5, 2026 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants