diff --git a/.github/workflows/agentics-maintenance.yml b/.github/workflows/agentics-maintenance.yml index 8c142f3ab1a..6eb35db87c3 100644 --- a/.github/workflows/agentics-maintenance.yml +++ b/.github/workflows/agentics-maintenance.yml @@ -281,7 +281,7 @@ jobs: validate_workflows: if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.operation == 'validate' && !github.event.repository.fork }} - runs-on: ubuntu-slim + runs-on: ubuntu-latest permissions: contents: read issues: write diff --git a/actions/setup/js/effective_tokens.cjs b/actions/setup/js/effective_tokens.cjs index 91955653be0..7c817a9f43e 100644 --- a/actions/setup/js/effective_tokens.cjs +++ b/actions/setup/js/effective_tokens.cjs @@ -208,6 +208,21 @@ function _resetCache() { _parsedMultipliers = undefined; } +/** + * Read effective tokens from the GH_AW_EFFECTIVE_TOKENS environment variable and return + * a pre-formatted suffix string suitable for appending to footer text. + * Returns "" when the variable is absent or the parsed value is not a positive integer. + * @returns {string} Suffix string, e.g. " · ● 12.5K" or "" + */ +function getEffectiveTokensSuffix() { + const raw = process.env.GH_AW_EFFECTIVE_TOKENS; + const parsed = raw ? parseInt(raw, 10) : NaN; + if (!isNaN(parsed) && parsed > 0) { + return ` · ● ${formatET(parsed)}`; + } + return ""; +} + module.exports = { defaultTokenClassWeights, getTokenClassWeights, @@ -215,5 +230,6 @@ module.exports = { computeBaseWeightedTokens, computeEffectiveTokens, formatET, + getEffectiveTokensSuffix, _resetCache, }; diff --git a/actions/setup/js/handle_detection_runs.cjs b/actions/setup/js/handle_detection_runs.cjs index e0a595b0c0d..ff86d0e3de4 100644 --- a/actions/setup/js/handle_detection_runs.cjs +++ b/actions/setup/js/handle_detection_runs.cjs @@ -7,6 +7,7 @@ const { ERR_API } = require("./error_codes.cjs"); const { sanitizeContent } = require("./sanitize_content.cjs"); const { generateFooterWithExpiration } = require("./ephemerals.cjs"); const { renderTemplateFromFile } = require("./messages_core.cjs"); +const { getEffectiveTokensSuffix } = require("./effective_tokens.cjs"); /** * Search for or create the parent issue for all agentic workflow detection runs. @@ -107,11 +108,16 @@ async function main() { // Load and render comment template from file const commentTemplatePath = `${process.env.RUNNER_TEMP}/gh-aw/prompts/detection_runs_comment.md`; + + // Compute effective tokens suffix from environment variable (set by parse_token_usage.cjs / parse_mcp_gateway_log.cjs) + const effectiveTokensSuffix = getEffectiveTokensSuffix(); + const commentBody = renderTemplateFromFile(commentTemplatePath, { workflow_name: workflowName, conclusion: detectionConclusion, reason: detectionReason || "unknown", run_url: runUrl, + effective_tokens_suffix: effectiveTokensSuffix, }); // Sanitize the full comment body diff --git a/actions/setup/js/handle_noop_message.cjs b/actions/setup/js/handle_noop_message.cjs index 0a3b8a8db8a..e583b6e310c 100644 --- a/actions/setup/js/handle_noop_message.cjs +++ b/actions/setup/js/handle_noop_message.cjs @@ -9,6 +9,7 @@ const { generateFooterWithExpiration } = require("./ephemerals.cjs"); const { renderTemplateFromFile } = require("./messages_core.cjs"); const { loadAgentOutput } = require("./load_agent_output.cjs"); const { isStagedMode } = require("./safe_output_helpers.cjs"); +const { getEffectiveTokensSuffix } = require("./effective_tokens.cjs"); /** * Search for or create the parent issue for all agentic workflow no-op runs @@ -184,10 +185,15 @@ async function main() { // Load and render comment template from file const commentTemplatePath = `${process.env.RUNNER_TEMP}/gh-aw/prompts/noop_comment.md`; + + // Compute effective tokens suffix from environment variable (set by parse_token_usage.cjs / parse_mcp_gateway_log.cjs) + const effectiveTokensSuffix = getEffectiveTokensSuffix(); + const commentBody = renderTemplateFromFile(commentTemplatePath, { workflow_name: workflowName, message: noopMessage, run_url: runUrl, + effective_tokens_suffix: effectiveTokensSuffix, }); // Sanitize the full comment body diff --git a/actions/setup/js/handle_noop_message.test.cjs b/actions/setup/js/handle_noop_message.test.cjs index b52ae831124..67790ca2aec 100644 --- a/actions/setup/js/handle_noop_message.test.cjs +++ b/actions/setup/js/handle_noop_message.test.cjs @@ -76,7 +76,7 @@ This issue helps you: {message} -> Generated from [{workflow_name}]({run_url})`; +> Generated from [{workflow_name}]({run_url}){effective_tokens_suffix}`; } return originalReadFileSync.call(fs, filePath, encoding); }); @@ -669,4 +669,63 @@ This issue helps you: // Verify XSS attempt was sanitized (specific behavior depends on sanitizeContent implementation) expect(commentCall.body).not.toContain("