Skip to content

Prefix effective-token footer values with deterministic 5-char model IDs#34291

Merged
pelikhan merged 5 commits into
mainfrom
copilot/improve-footer-token-rendering
May 23, 2026
Merged

Prefix effective-token footer values with deterministic 5-char model IDs#34291
pelikhan merged 5 commits into
mainfrom
copilot/improve-footer-token-rendering

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 23, 2026

Effective token values in generated footers now include a compact model identifier prefix so readers can instantly see which model produced the usage signal (e.g., son46, gpt55, opu47).
This adds a deterministic reducer with well-known shortcuts and wires it into footer suffix rendering paths.

  • Model identifier reduction

    • Added reduceModelNameToIdentifier(modelName) in actions/setup/js/effective_tokens.cjs.
    • Implements stable 5-char IDs with family shortcuts for popular models:
      • sonnet -> sonNN
      • gpt -> gptNN
      • opus -> opuNN
      • haiku -> haiNN
      • gemini -> gemNN
    • Includes deterministic fallback for unknown model names.
  • Footer effective-token rendering

    • Updated effective-token suffix generation to prepend reduced model IDs when GH_AW_ENGINE_MODEL is present.
    • Footer output now renders as · ● <modelId> <formattedET> instead of · ● <formattedET>.
  • Safe-output footer integration

    • Updated actions/setup/js/messages_footer.cjs to use the same reducer path for:
      • default footer rendering
      • custom templates using {effective_tokens_suffix}
      • related footer helpers that source ET from environment context
  • Targeted behavior coverage

    • Expanded tests in:
      • actions/setup/js/effective_tokens.test.cjs
      • actions/setup/js/messages.test.cjs
    • Added cases for canonical shortcuts, date-like suffix handling, fallback IDs, and footer/template rendering.
// before
"> Generated by [Workflow](...) · ● 12.5K"

// after (GH_AW_ENGINE_MODEL=claude-sonnet-4.6)
"> Generated by [Workflow](...) · ● son46 12.5K"

Copilot AI and others added 3 commits May 23, 2026 19:45
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Improve effective-token footer rendering with compact model identifiers Prefix effective-token footer values with deterministic 5-char model IDs May 23, 2026
Copilot AI requested a review from pelikhan May 23, 2026 19:50
@pelikhan pelikhan marked this pull request as ready for review May 23, 2026 19:51
Copilot AI review requested due to automatic review settings May 23, 2026 19:51
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

🧪 Test Quality Sentinel completed test quality analysis.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #34291 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold is 100).

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

⚠️ PR Code Quality Reviewer failed during code quality review.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 23, 2026

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

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

This PR adds a deterministic, compact (5-character) model identifier and prefixes effective-token (ET) footer values with it so readers can quickly see which model produced the usage signal (e.g., son46 12.5K).

Changes:

  • Added reduceModelNameToIdentifier(modelName) (with well-known family shortcuts + deterministic fallback) and updated getEffectiveTokensSuffix() to include the reduced model prefix when GH_AW_ENGINE_MODEL is set.
  • Updated footer rendering paths (default and templated {effective_tokens_suffix}) to prepend the reduced model identifier when available.
  • Expanded unit tests to cover model reduction, date-like suffix handling, fallback IDs, and footer/template output.
Show a summary per file
File Description
actions/setup/js/effective_tokens.cjs Introduces deterministic 5-char model ID reduction and prefixes ET suffix output with the reduced model ID when available.
actions/setup/js/messages_footer.cjs Wires model ID reduction into footer ET suffix generation for both default and templated footers.
actions/setup/js/effective_tokens.test.cjs Adds tests for model ID reduction and for model-prefixed ET suffix behavior.
actions/setup/js/messages.test.cjs Adds footer tests ensuring model-prefixed ET rendering for default and custom-template suffix paths.

Copilot's findings

Tip

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

  • Files reviewed: 4/4 changed files
  • Comments generated: 0

@github-actions github-actions Bot mentioned this pull request May 23, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /tdd, /grill-with-docs, and /zoom-out — overall a clean, well-structured feature with good baseline test coverage. No blocking issues, but a few areas worth addressing before merge.

📋 Key Themes & Highlights

Key Themes

  • Test coverage gaps: haiku and gemini shortcuts are declared but untested; null/undefined input contract is unverified.
  • Date-like heuristic ambiguity: ^\d{3,}$ suppresses any 3+ digit minor segment, not just calendar stamps — the threshold deserves a comment or a narrower regex.
  • Duplicate suffix computation: In getFooterMessage, getEffectiveTokensFromEnv returns an effectiveTokensSuffix that is silently discarded and rebuilt moments later — a minor architectural inconsistency.

Positive Highlights

  • ✅ Deterministic fallback (buildFallbackModelIdentifier) handles arbitrary model names without crashing or producing unbounded output.
  • normalizeVersionDigits date-suppression logic is well-commented and makes the intent clear.
  • ✅ Integration tests in messages.test.cjs verify end-to-end footer rendering with the new prefix — good coverage of the happy path.
  • ✅ Exporting reduceModelNameToIdentifier from the module makes it independently testable.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● son46 1.7M


test("returns deterministic 5-character fallback for unknown models", () => {
expect(reduceModelNameToIdentifier("my-custom-engine-v2")).toBe("myc20");
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] haiku and gemini shortcuts are declared in the shortcuts array but have no test coverage — leaving two of the five known families unverified.

💡 Suggested tests
test("uses well-known haiku shortcut", () => {
  expect(reduceModelNameToIdentifier("claude-haiku-4.5")).toBe("hai45");
});

test("uses well-known gemini shortcut", () => {
  expect(reduceModelNameToIdentifier("gemini-2.5-pro")).toBe("gem25");
});

If a regex or prefix typo were introduced for either family, it would only be caught at runtime.

expect(formatET(999)).toBe("999");
});

describe("reduceModelNameToIdentifier", () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] The reduceModelNameToIdentifier test suite doesn't cover null, undefined, or an empty string — all of which the implementation handles, but the contract isn't pinned by a test.

💡 Suggested tests
test("returns empty string for null input", () => {
  expect(reduceModelNameToIdentifier(null)).toBe("");
});
test("returns empty string for undefined input", () => {
  expect(reduceModelNameToIdentifier(undefined)).toBe("");
});
test("returns empty string for empty string input", () => {
  expect(reduceModelNameToIdentifier("")).toBe("");
});

Without these, a refactor that accidentally breaks the null-guard would go undetected.

const majorDigit = getFirstDigit(major);
// Date-like suffixes (e.g. 20250514) are build/release stamps, not semantic minor versions.
// Treat them as missing so identifiers stay stable (gpt-5-2025-08-07 -> gpt50).
const minorIsDateLike = minor && /^\d{3,}$/.test(minor);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/grill-with-docs] The date-like detection regex ^\d{3,}$ suppresses any minor token with 3+ digits — not just actual date stamps. gpt-4-100 would produce gpt40 (100 treated as date-like), which may be surprising for non-date version numbers.

💡 Consider narrowing the heuristic

If the intent is specifically to suppress 8-digit YYYYMMDD stamps or 4+ digit year prefixes, a more precise pattern like /^\d{8}$|^20\d{2}/ would avoid false positives on smaller numbers.

Alternatively, document the current threshold explicitly:

// Treat any 3+ digit minor segment as a build/date stamp (e.g. "100", "20250514")
// to keep identifiers stable across date-stamped releases.
const minorIsDateLike = minor && /^\d{3,}$/.test(minor);

Either way, a test case like reduceModelNameToIdentifier("gpt-4-100") would pin the current behaviour.

Comment thread actions/setup/js/messages_footer.cjs Outdated
// still get the effective token count in the footer when GH_AW_EFFECTIVE_TOKENS is set.
const { effectiveTokens: envEffectiveTokens } = getEffectiveTokensFromEnv();
const resolvedModelName = ctx.model || process.env.GH_AW_ENGINE_MODEL || "";
const { effectiveTokens: envEffectiveTokens } = getEffectiveTokensFromEnv(resolvedModelName);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/zoom-out] getEffectiveTokensFromEnv(resolvedModelName) computes and returns an effectiveTokensSuffix (including model prefix) that is immediately discarded — only effectiveTokens (the raw number) is destructured. The suffix is then rebuilt independently at line 103. This split makes the function's signature misleading for this call-site.

💡 Options to resolve

Option A — use the suffix already built by getEffectiveTokensFromEnv directly:

const { effectiveTokens: envEffectiveTokens, effectiveTokensSuffix: envSuffix } = getEffectiveTokensFromEnv(resolvedModelName);
// then use envSuffix rather than rebuilding it below

Option B — keep getEffectiveTokensFromEnv model-agnostic (just parse the env var number), and move all model-prefix logic to the callers that need it. This would reduce the function's responsibility and make the suffix computation visible at each call-site.

Either choice avoids the current situation where the same suffix is computed twice for the getFooterMessage path.

@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 83/100 — Excellent

Analyzed 9 test(s): 9 design, 0 implementation, 0 guideline violation(s).

📊 Metrics & Test Classification (9 tests analyzed)
Metric Value
New/modified tests analyzed 9
✅ Design tests (behavioral contracts) 9 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 4 (44%)
Duplicate test clusters 0
Test inflation detected No
🚨 Coding-guideline violations 0

Test Classification Details

Test File Classification Issues Detected
uses well-known sonnet shortcut actions/setup/js/effective_tokens.test.cjs:344 ✅ Design None
uses well-known gpt shortcut actions/setup/js/effective_tokens.test.cjs:348 ✅ Design None
uses well-known opus shortcut actions/setup/js/effective_tokens.test.cjs:352 ✅ Design None
handles date-like suffixes deterministically actions/setup/js/effective_tokens.test.cjs:356 ✅ Design None (edge case coverage ✓)
returns deterministic 5-character fallback for unknown models actions/setup/js/effective_tokens.test.cjs:361 ✅ Design None (edge case coverage ✓)
prepends reduced model identifier when model is available actions/setup/js/effective_tokens.test.cjs:371 ✅ Design None
falls back to token-only suffix when model is unavailable actions/setup/js/effective_tokens.test.cjs:377 ✅ Design None (edge case coverage ✓)
should prepend reduced model identifier to effective tokens when engine model is set actions/setup/js/messages.test.cjs:369 ✅ Design None
should include reduced model identifier in effective_tokens_suffix for custom templates actions/setup/js/messages.test.cjs:442 ✅ Design None (edge case coverage ✓)

Language Support

Tests analyzed:

  • 🟨 JavaScript (*.test.cjs, *.test.js): 9 tests (vitest)

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%).

📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

🧪 Test quality analysis by Test Quality Sentinel · ● son45 1.1M ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 83/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%).

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review all comments and reviews including from GitHub-actions shop

Copilot AI and others added 2 commits May 23, 2026 20:13
…uffix reuse

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 23, 2026

@copilot review all comments and reviews including from GitHub-actions shop

Reviewed all PR comments/reviews (including github-actions) and addressed the actionable items in 59e05c1 and follow-up cleanup in eed1bbd.

Updates include:

  • added missing reducer tests (haiku/gemini/null/undefined/empty and gpt-4-100 behavior)
  • clarified the 3+ digit minor-segment heuristic comment
  • removed duplicate footer suffix recomputation by reusing env-derived suffix values in getFooterMessage

Targeted lint/tests pass, and final parallel validation is clean.

@pelikhan pelikhan merged commit b829582 into main May 23, 2026
@pelikhan pelikhan deleted the copilot/improve-footer-token-rendering branch May 23, 2026 20:20
github-actions Bot added a commit that referenced this pull request May 24, 2026
…ID prefix

Documents two user-facing changes merged 2026-05-23/24:

- #34239: compiler warning when prompts reference /tmp/ or /tmp/gh-aw/
  directly. Added a "Temporary File Paths in Prompts" section to the
  Markdown reference describing the convention and the warning text.
- #34291: 5-character model ID prefix (sonNN/gptNN/opuNN/haiNN/gemNN)
  in the effective-token footer suffix. Updated the
  {effective_tokens_suffix} description in safe-outputs and footers
  references to show the new shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants