Skip to content

⚡ Copilot Token Optimization2026-08-31 — Duplicate Code Detector #7883

Description

@github-actions

Target Workflow: duplicate-code-detector

Source report: #7881
Estimated cost per run: $0.00 (billed via Copilot subscription; AI credits: ~7.25 AIC/run)
Total tokens per run: ~458.5K (single run analyzed: run 33337001582)
Cache hit rate: 90% (411,648 / 456,219 input tokens served from cache)
LLM turns: 12 (prompt caps this at "≤4 turns" but the run took 12)

Current Configuration

Setting Value
Tools loaded 2 (github restricted to toolsets: [issues], bash: true)
Tools actually used Both loaded tools are used (bash for cat/sed/grep; github for issue creation via safe-outputs)
Network groups github only (already minimal)
Pre-agent steps Yes — jscpd install/run, file metrics, grep patterns, existing-issues check all pre-computed in steps:
Prompt size 7,405 chars (body + frontmatter)

Despite already following most best practices (pre-agent steps, restricted github toolset, single network group), this workflow is still the most token-intensive workflow in the repo (458.5K tokens vs. next-highest at 176K). The root cause is not tool surface or missing pre-computation — it's turn count: 12 LLM turns were used even though the prompt explicitly instructs "Complete your analysis in ≤4 turns." Because each turn resends the growing conversation transcript (input tokens climbed from 25,626 → 43,221 across the 12 requests), tokens accumulate almost linearly with turn count, and cache reads (90% hit rate) only discount repeated prefix tokens — they don't eliminate the linear growth from restating tool outputs and analysis in each new turn.

Recommendations

1. Enforce a hard turn budget and shrink per-turn output

Estimated savings: ~230K tokens/run (~50%), based on cutting 12 turns → ~5-6 turns at the same growth rate

The workflow prompt already says "Complete your analysis in ≤4 turns" but the actual run used 12 — the instruction isn't being followed because it's advisory text buried in a "Scope Constraint" section rather than a structural limit. Add an explicit engine: turn cap and restructure the prompt so all analysis/decision-making happens in one pass:

engine:
  id: copilot
  max-turns: 6   # hard cap; forces single-pass analysis instead of iterative exploration

Also collapse the "Phase 5" (check existing issues) and "Phase 6" (prioritize/report) sections into one instruction block so the agent doesn't treat them as sequential turns:

## Analysis and Reporting (single pass)

1. Read all four pre-computed files listed above in this turn.
2. Score and rank duplications using the table below.
3. For findings scoring ≥4 that are not already OPEN in `/tmp/gh-aw/existing-issues.json`,
   create up to 3 issues **in the same turn** using the `create-issue` safe-output tool.
   Do not make additional tool calls to re-read files you've already read.

2. Reduce redundant file re-reads across turns

Estimated savings: ~80K tokens/run (~17%)

The pre-computed files (code-metrics.txt, jscpd-top.json, grep-analysis.txt, existing-issues.json) are read via bash (cat ...), and each sed -n 'X,Yp' src/file.ts evidence-gathering call adds a new tool round-trip that re-sends the full conversation history. Instead of allowing arbitrary sed calls per finding, pre-extract the specific evidence line ranges as part of the jscpd summarization step (Run jscpd), since jscpd-top.json already contains start/end line numbers:

  - name: Run jscpd
    run: |
      jscpd src --min-lines 10 --min-tokens 50 --reporters json --output /tmp/gh-aw/jscpd-src 2>&1 | tail -20 > /tmp/gh-aw/jscpd-src.txt
      if [ -f /tmp/gh-aw/jscpd-src/jscpd-report.json ]; then
        jq '{...}' /tmp/gh-aw/jscpd-src/jscpd-report.json > /tmp/gh-aw/jscpd-top.json
        # NEW: pre-extract code snippets for top findings so the agent doesn't need bash calls
        python3 scripts/ci/extract-duplicate-snippets.py /tmp/gh-aw/jscpd-top.json > /tmp/gh-aw/jscpd-evidence.json
      fi

This turns ~6-8 evidence-gathering bash tool calls into a single cat /tmp/gh-aw/jscpd-evidence.json read.

3. Trim bash: true to a scoped command allowlist

Estimated savings: ~5-10K tokens/run (~2%) plus reduced risk of exploratory re-runs

bash: true grants unrestricted shell access, which can tempt the agent to re-run discovery commands (find, grep, jscpd) instead of using the pre-computed files, contributing to extra turns. Restrict to only the commands actually needed for evidence display:

tools:
  github:
    toolsets: [issues]
  bash:
    allowed:
      - "cat *"
      - "sed -n *"

This won't reduce tokens directly but removes the temptation/ability to re-run jscpd/find/grep mid-session, which is likely part of why turns grew from the planned 4 to the observed 12.

Expected Impact

Metric Current Projected Savings
Total tokens/run 458.5K ~150-230K ~50-67%
LLM turns 12 ≤6 -6
Cache hit rate 90% ~90% (unchanged, already good)
Session duration 4.0m ~2m (est.) ~50%

Implementation Checklist

  • Add max-turns: 6 under engine: in duplicate-code-detector.md
  • Merge "Phase 5" and "Phase 6" prompt sections into a single-pass analysis block
  • Add a pre-agent step to extract code evidence snippets (avoid per-finding sed tool calls)
  • Restrict bash: to an allowlist (cat *, sed -n *) instead of bash: true
  • Recompile: gh aw compile .github/workflows/duplicate-code-detector.md
  • Post-process: npx tsx scripts/ci/postprocess-smoke-workflows.ts
  • Verify CI passes on PR
  • Compare token usage on new run vs. baseline (458.5K tokens, 12 turns)

Generated by Daily Copilot Token Optimization Advisor · copilot · auto · 44.8 AIC · ⊞ 10.7K ·

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions