Skip to content

refactor(token-tracker-http): decompose 238-line trackTokenUsage into testable top-level functions#4937

Merged
lpcox merged 2 commits into
mainfrom
copilot/decompose-track-token-usage
Jun 14, 2026
Merged

refactor(token-tracker-http): decompose 238-line trackTokenUsage into testable top-level functions#4937
lpcox merged 2 commits into
mainfrom
copilot/decompose-track-token-usage

Conversation

Copilot AI commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

trackTokenUsage in token-tracker-http.js contained two untestable inner functions (handleDecodedChunk, finalizeTracking) that closed over ~12 outer-scope variables, making unit testing impossible without constructing a full http.IncomingMessage stream.

Changes

token-tracker-http.js

Extracted all inner functions to top-level, each accepting explicit state instead of relying on closure:

  • initHttpState(flags) — constructs the mutable tracking state object (chunks, streamingUsage, partialLine, overflow flags, etc.)
  • createChunkHandler(state, { requestId, provider }) — returns the handleDecodedChunk function; mutates state by reference, no outer-scope capture
  • wireListeners(proxyRes, decompressor, state, onChunk, onFinalize) — encapsulates the compressed/uncompressed event-listener branching
  • finalizeHttpTracking(state, proxyRes, opts) — the former finalizeTracking closure; takes all inputs explicitly so it's callable with a synthetic state object and a { statusCode } mock

trackTokenUsage shrinks to ~30 lines (init → handler → wire → finalize). Public API is unchanged; token-tracker.js requires no updates. createChunkHandler and finalizeHttpTracking are added to module.exports for direct testing.

// Before: one 238-line function with two embedded closures
function trackTokenUsage(proxyRes, opts) {
  // ...12 state variables...
  function handleDecodedChunk(text) { /* closes over all of them */ }
  function finalizeTracking() { /* closes over all of them */ }
}

// After: explicit state passed through top-level functions
function trackTokenUsage(proxyRes, opts) {
  const state = initHttpState({ streaming, compressed, contentType, contentEncoding });
  const onChunk = createChunkHandler(state, { requestId, provider });
  wireListeners(proxyRes, decompressor, state, onChunk,
    () => finalizeHttpTracking(state, proxyRes, opts));
}

token-tracker-http.unit.test.js (new)

18 unit tests for createChunkHandler and finalizeHttpTracking using synthetic state objects — covering SSE accumulation, partial-line buffering across chunks, overflow handling, non-2xx skip, streaming flush, onUsage/onSpanEnd callbacks, and error resilience.

Extract the two inner functions from the 238-line trackTokenUsage closure
into top-level functions that accept explicit state:

- initHttpState({ streaming, compressed, contentType, contentEncoding })
  Initialises the mutable tracking state object so it can be constructed
  independently in tests.

- createChunkHandler(state, { requestId, provider }) → handleDecodedChunk
  Returns the decoded-chunk handler; mutates `state` via explicit reference
  instead of closing over outer-scope variables.

- wireListeners(proxyRes, decompressor, state, onChunk, onFinalize)
  Encapsulates event-listener wiring (decompressed and uncompressed paths).

- finalizeHttpTracking(state, proxyRes, opts)
  The former inner `finalizeTracking` closure, now taking all inputs as
  explicit parameters so it can be unit-tested with a synthetic state object
  and a minimal `{ statusCode }` proxyRes mock.

trackTokenUsage is now ~30 lines (init → create handler → wire → finalize).
The public module API is unchanged; token-tracker.js requires no updates.

New exports: createChunkHandler, finalizeHttpTracking (alongside trackTokenUsage).
New test file: token-tracker-http.unit.test.js — 18 unit tests covering both
sub-functions directly without constructing a full HTTP response stream.

All 1062 existing tests continue to pass.

Closes #4934
Copilot AI changed the title [WIP] Refactor trackTokenUsage into testable sub-functions refactor(token-tracker-http): decompose 238-line trackTokenUsage into testable top-level functions Jun 14, 2026
Copilot finished work on behalf of lpcox June 14, 2026 17:04
Copilot AI requested a review from lpcox June 14, 2026 17:04
@lpcox lpcox marked this pull request as ready for review June 14, 2026 17:07
Copilot AI review requested due to automatic review settings June 14, 2026 17:07
@github-actions

Copy link
Copy Markdown
Contributor

✅ Coverage Check Passed

Overall Coverage

Metric Base PR Delta
Lines 96.60% 96.64% 📈 +0.04%
Statements 96.47% 96.51% 📈 +0.04%
Functions 98.80% 98.80% ➡️ +0.00%
Branches 91.18% 91.21% 📈 +0.03%
📁 Per-file Coverage Changes (1 files)
File Lines (Before → After) Statements (Before → After)
src/workdir-setup.ts 92.6% → 94.4% (+1.85%) 92.6% → 94.4% (+1.85%)

Coverage comparison generated by scripts/ci/compare-coverage.ts

Copilot AI left a comment

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.

Pull request overview

This PR refactors the API-proxy HTTP token usage tracker by extracting previously inner/closure-based logic from trackTokenUsage into top-level, state-driven helper functions, enabling direct unit testing without needing to construct an http.IncomingMessage stream.

Changes:

  • Extracted closure-captured logic into explicit, top-level functions (createChunkHandler, wireListeners, finalizeHttpTracking) operating on a mutable state object.
  • Simplified trackTokenUsage into a short orchestration function (init → handler → listener wiring → finalize).
  • Added a new unit test suite covering chunk handling and finalization behavior with synthetic state objects.
Show a summary per file
File Description
containers/api-proxy/token-tracker-http.js Decomposes trackTokenUsage internals into top-level, state-based helpers and exports key helpers for unit testing.
containers/api-proxy/token-tracker-http.unit.test.js Adds unit tests for createChunkHandler and finalizeHttpTracking using synthetic state objects.

Copilot's findings

Tip

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

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

@github-actions

Copy link
Copy Markdown
Contributor

🔥 Smoke Test Results — Auth mode: PAT (COPILOT_GITHUB_TOKEN)

Test Result
GitHub MCP connectivity
GitHub.com HTTP ✅ (200)
File write/read

Overall: PASS

CC @lpcox @Copilot

🔑 PAT report filed by Smoke Copilot PAT

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Direct) Mode

  • ✅ GitHub MCP connectivity verified
  • ✅ github.com reachable (HTTP 200)
  • ✅ File write/read functional
  • ✅ BYOK inference path working (api-proxy → api.githubcopilot.com)

Status: PASS | Mode: direct BYOK (COPILOT_PROVIDER_API_KEY)

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

Copy link
Copy Markdown
Contributor

🔬 Smoke Test Results — PASS

Test Result
GitHub MCP connectivity
GitHub.com HTTP ✅ 200
File write/read

PR: refactor(token-tracker-http): decompose 238-line trackTokenUsage into testable top-level functions
Author: @CopilotAssignees: @lpcox, @Copilot

Overall: PASS

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

Copy link
Copy Markdown
Contributor

Smoke test results:

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions

Copy link
Copy Markdown
Contributor

Smoke test results for PR #4937:

  • MCP connectivity: ✅
  • GitHub.com HTTP: ✅
  • File write/read: ✅
  • BYOK direct mode: ✅

Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra

Overall: PASS

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@github-actions

Copy link
Copy Markdown
Contributor

🔬 Smoke Test: API Proxy OpenTelemetry Tracing

Scenario Result Notes
1. Module Loading otel.js loads OK; exports: startRequestSpan, setTokenAttributes, setBudgetAttributes, endSpan, endSpanError, shutdown, isEnabled + internal helpers
2. Test Suite otel.test.js: 39/39 passed; token-tracker-http.unit.test.js: 18/18 passed
3. Env Var Forwarding OTEL_* vars forwarded via agent-environment-credentials.ts; 3 OTEL-specific tests pass
4. Token Tracker Integration onUsage callback present in finalizeHttpTracking (lines 251–253); onSpanEnd also wired; both exported for direct testing
5. OTEL Diagnostics No remote OTEL endpoint configured → spans written to local file fallback (/var/log/api-proxy/otel.jsonl); no export errors
6. Graceful Degradation otel.js always enables (file fallback active); no errors when OTEL_EXPORTER_OTLP_ENDPOINT is unset

All 6 scenarios pass. The OTEL integration is functioning correctly on this PR.

📡 OTel tracing validated by Smoke OTel Tracing

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.16.0 v22.22.3
Go go1.22.12 go1.22.12

Overall: ❌ Not all tests passed

Go versions match, but Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results — Services Connectivity

Check Result
Redis PING ❌ No response (timeout)
PostgreSQL pg_isready ❌ No response
PostgreSQL SELECT 1 ❌ No response (timeout)

Overall: FAIL

host.docker.internal is not reachable from this runner environment (not running inside a Docker container). Services are also not available on localhost. GitHub Actions service containers may not be configured or accessible in this context.

🔌 Service connectivity validated by Smoke Services

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results

  • GitHub MCP Testing: ❌ (Tools not found)
  • GitHub.com Connectivity: ❌ (HTTP 000)
  • File Writing Testing: ✅
  • Bash Tool Testing: ✅

Overall status: FAIL

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • localhost

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

💎 Faceted by Smoke Gemini

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx passed ✅ PASS
Node.js execa passed ✅ PASS
Node.js p-limit passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #4937 ·

@lpcox lpcox merged commit 1a4fde6 into main Jun 14, 2026
80 of 87 checks passed
@lpcox lpcox deleted the copilot/decompose-track-token-usage branch June 14, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants