perf(export-audit): move phases 1–3 to pre-steps, cut ~75% token usage#3077
Conversation
🔥 Smoke Test: Copilot BYOK (Offline) Mode
Running in BYOK offline mode ( Overall: PASS
|
🔍 Smoke Test Results
Overall: FAIL — GitHub MCP returned 401; pre-step template outputs were not expanded into the agent prompt.
|
Smoke Test Results✅ Playwright: Navigated to github.com, title verified Status: 2/3 PASS
|
There was a problem hiding this comment.
Pull request overview
This PR optimizes the export-audit agentic workflow by shifting deterministic analysis (unused exports, circular deps, naming checks) into pre-agent GitHub Actions steps and then feeding the results into the prompt, reducing tool round-trips and prompt size.
Changes:
- Added pre-steps to compute
UNUSED_EXPORTS,CIRCULAR_DEPS, andNAMING_ISSUES, and referenced them in the prompt instead of running inline bash phases. - Capped potentially unbounded loop output in later phases with
headto limit context growth. - Updated compiled lock workflow to wire new step outputs into prompt rendering and reduced the agent firewall domain set (removed
nodegroup).
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/export-audit.md | Moves phases 1–3 into pre-steps and updates prompt to consume their outputs; caps later-phase loop outputs. |
| .github/workflows/export-audit.lock.yml | Recompiled workflow to include new steps/outputs and updated firewall allowed domains accordingly. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
.github/workflows/export-audit.md:202
- Same issue in Phase 5:
basename "$f" != "index.js"is not a valid test and will likely skip all provider files. Replace with a bracket test (e.g.,[ "$(basename "$f")" != "index.js" ]) so the audit inspects each provider module.
echo "=== api-proxy/providers: check export consistency ==="
for f in containers/api-proxy/providers/*.js; do
[ -f "$f" ] && basename "$f" != "index.js" || continue
echo "--- $f ---"
grep -n "^module\.exports\|^exports\." "$f" | head -5
done | head -50
- Files reviewed: 2/2 changed files
- Comments generated: 4
| grep -v "^[A-Z]" | head -20 | ||
| echo "=== api-proxy provider exports ===" | ||
| for f in containers/api-proxy/providers/*.js; do | ||
| [ -f "$f" ] && basename "$f" != "index.js" || continue |
| - name: Detect unused exports (ts-prune) | ||
| id: unused_exports | ||
| run: | | ||
| { | ||
| echo "UNUSED_EXPORTS<<EOF" | ||
| npm install -g ts-prune 2>/dev/null | tail -5 | ||
| ts-prune 2>/dev/null | grep -v "\.test\.ts" | head -40 || \ | ||
| grep -rn "^export " src/ --include="*.ts" | grep -v "\.test\.ts" | \ | ||
| while IFS=: read -r file line rest; do | ||
| name=$(echo "$rest" | sed -n 's/.*export \(function\|class\|const\|type\|interface\|enum\) \([a-zA-Z_][a-zA-Z0-9_]*\).*/\2/p') | ||
| [ -z "$name" ] && continue | ||
| count=$(grep -rwn "${name}" src/ --include="*.ts" 2>/dev/null | grep -v "^${file}:" | wc -l) | ||
| [ "$count" -eq 0 ] && echo "UNUSED: $name ($file:$line)" | ||
| done | head -30 | ||
| echo "EOF" |
| - name: Detect circular dependencies (madge) | ||
| id: circular_deps | ||
| run: | | ||
| { | ||
| echo "CIRCULAR_DEPS<<EOF" | ||
| npm install -g madge 2>/dev/null | tail -5 | ||
| madge --circular src/ 2>/dev/null | head -20 || echo "No circular deps detected" | ||
| echo "EOF" | ||
| } >> "$GITHUB_OUTPUT" |
| npm install -g ts-prune 2>/dev/null | tail -5 | ||
| ts-prune 2>/dev/null | grep -v "\.test\.ts" | head -40 || \ | ||
| grep -rn "^export " src/ --include="*.ts" | grep -v "\.test\.ts" | \ | ||
| while IFS=: read -r file line rest; do | ||
| name=$(echo "$rest" | sed -n 's/.*export \(function\|class\|const\|type\|interface\|enum\) \([a-zA-Z_][a-zA-Z0-9_]*\).*/\2/p') | ||
| [ -z "$name" ] && continue | ||
| count=$(grep -rwn "${name}" src/ --include="*.ts" 2>/dev/null | grep -v "^${file}:" | wc -l) | ||
| [ "$count" -eq 0 ] && echo "UNUSED: $name ($file:$line)" | ||
| done | head -30 |
|
Smoke Test Codex: FAIL Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "registry.npmjs.org"See Network Configuration for more information.
|
🏗️ Build Test Suite Results
Overall: 8/8 ecosystems passed — ✅ PASS
|
Smoke Test Results
Overall: FAIL —
|
Gemini Smoke Test Results
Overall status: FAIL Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "localhost"See Network Configuration for more information.
|
|
@copilot address review feedback |
Done in commit
|
✨ Enhancement
What does this improve?
export-auditwas averaging ~414K input tokens/run because the agent ran 6 bash analysis phases inline, each appending tool output to the LLM context window. Phases 1–3 (unused exports, circular deps, naming conventions) are purely deterministic — they only need judgment to interpret, not to run.Why is this valuable?
node+githubgithubonlyImplementation approach:
Moved Phases 1–3 to pre-agent
steps:—unused_exports(ts-prune + grep fallback),circular_deps(madge), andnaming_auditnow run as deterministic pre-steps and emit compact outputs via$GITHUB_OUTPUT. The agent receives the results as pre-computed data, eliminating 6–10 inline bash round-trips from the LLM context.Replaced Phases 1–3 prompt blocks with lightweight review instructions referencing the step outputs:
Unused exports: ${{ steps.unused_exports.outputs.UNUSED_EXPORTS }} Circular dependencies: ${{ steps.circular_deps.outputs.CIRCULAR_DEPS }} Naming issues: ${{ steps.naming_audit.outputs.NAMING_ISSUES }}Hard-capped nested loop output in Phases 4–5 with
| head -50to prevent unbounded output from test file import loops and api-proxy provider loops.Removed
nodefromnetwork.allowed— npm registry access is no longer needed at agent runtime sincets-prune/madgeinstalls now happen in pre-steps.Recompiled
export-audit.lock.ymland ran post-processing.