feat: aggregate AI credits from aggregated usage JSONL files in conclusion post-step#38506
Closed
Copilot wants to merge 16 commits into
Closed
feat: aggregate AI credits from aggregated usage JSONL files in conclusion post-step#38506Copilot wants to merge 16 commits into
Copilot wants to merge 16 commits into
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The conclusion job's post-step telemetry had no mechanism to read AI metric data stored as aggregated JSONL files in
/tmp/gh-aw/usage/— those files were deleted before their data could be captured. This adds explicit handling to parse and emit AI credits from the aggregated usage files before the temp folder is removed, with support for multiple possible file locations to handle different artifact download structures.Changes
pkg/constants/job_constants.goAgentUsageJsonlFilenameandDetectionUsageJsonlFilename— these were obsolete since AI credit usage files are now aggregated directly from sandbox locationspkg/workflow/notify_comment.gobuildUsageArtifactUploadStepsto remove references to obsolete intermediate usage filessend_otlp_span.cjsAGENTS_USAGE_JSONL_PATHS— 4 possible locations for agent usage filesDETECTION_USAGE_JSONL_PATHS— 4 possible locations for detection usage filesPAYLOAD_PREVIEW_MAX_LENGTH(500 chars for log truncation)parseAICreditsFromUsageJsonl(filePath): reads a JSONL file, sums AI credits across all entries; returns0on any error (missing file, malformed lines, etc.)ai_credits(legacy/standard),ai_credits_this_response(firewall logs), andaiCredits(camelCase variant)parseAICreditsFromMultiplePaths(filePaths, sourceLabel): tries multiple file paths in order using first-available-wins semanticsreadApiProxySteeringEventCountfunctionfs.existsSynccheck with logging to report when files exist, are missing, or encounter read errors for better diagnosticsextractAttributeValue(attr): extracts numeric values from OTLP attribute objects (handles bothintValueanddoubleValuefields)sendJobConclusionSpan: whenjobName === "conclusion"and nogh-aw.aicattribute has already been set, reads from multiple possible locations and emits:gh-aw.aic— combined total from both sourcesgh-aw.aic.agent— agent-only credits (when > 0)gh-aw.aic.detection— detection-only credits (when > 0)core.infologging for conclusion job spans including usage file paths, parsed AIC values, file existence status, span metadata (trace/span IDs, status), attribute count, AI credit breakdown, and payload size/preview for diagnosticsshim.cjsto ensurecore.infoworks in both GitHub Actions and standalone execution contextsMulti-path locations checked (in order):
Agent paths:
/tmp/gh-aw/usage/agent/token_usage.jsonl/tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl/tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl/tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonlDetection paths:
/tmp/gh-aw/usage/detection/token_usage.jsonl/tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl/tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl/tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonlThe guard
typeof aiCredits !== "number"makes source precedence explicit — the conclusion job is excluded fromjobEmitsOwnTokenUsage, soaiCreditsis alwaysundefinedat that point and the usage files are the sole AIC source.action_conclusion_otlp.cjscore.infoinstead ofconsole.logfor consistent logging across all execution contextsshim.cjsfor compatibilitysend_otlp_span.test.cjsparseAICreditsFromUsageJsonl(absent/empty file, multi-entry sum, camelCase field, firewall log field names, negative/non-numeric values, numeric strings, field preference ordering)parseAICreditsFromMultiplePaths(no files exist, first file found, first-available-wins semantics, multi-entry sum, empty file handling)GH_AW_AGENT_OUTPUTgh-aw.aic.agentandgh-aw.aic.detectionattributesfs.existsSyncfor proper test coverage of file existence checks and multi-path scenariosaction_conclusion_otlp.test.cjsglobal.core.infofor consistent test behaviorpkg/workflow/notify_comment_test.go✨ PR Review Safe Output Test - Run 27327422914
> [!WARNING]
>
> 💥 THE END] — Illustrated by [Smoke Claude · 66.4 AIC · ⌖ 25.5 AIC · ◷
Changeset
> Generated by 📋 Changeset Generator for issue #38506 · ◷
✨ PR Review Safe Output Test - Run 27329688421
> [!WARNING]
>
> 💥 THE END] — Illustrated by [Smoke Claude · 78.1 AIC · ⌖ 9.1 AIC · ◷
✨ PR Review Safe Output Test - Run 27331325626
> [!WARNING]
>
> 💥 THE END] — Illustrated by [Smoke Claude · 58.2 AIC · ⌖ 31.1 AIC · ◷
✨ PR Review Safe Output Test - Run 27346209016
> [!WARNING]
>
> 💥 THE END] — Illustrated by [Smoke Claude · 64.7 AIC · ⌖ 25.5 AIC · ◷