Skip to content

Refactor API proxy request path into focused guard and transport modules#3159

Merged
lpcox merged 3 commits into
mainfrom
copilot/refactor-api-proxy-modules
May 14, 2026
Merged

Refactor API proxy request path into focused guard and transport modules#3159
lpcox merged 3 commits into
mainfrom
copilot/refactor-api-proxy-modules

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

✨ Enhancement

containers/api-proxy/proxy-request.js had grown into a 1,196-line mixed-responsibility module (guards, steering, body mutation, rate limiting, HTTP, WebSocket) in a security-critical credential injection path. This change decomposes those concerns into focused modules while preserving the existing proxy-request public API for callers.

What does this improve?

  • Reduces cognitive load and review surface in the proxy hot path.
  • Isolates stateful guard logic from transport code, making future changes more localized.

Why is this valuable?

  • Lowers risk when modifying security-sensitive forwarding behavior.
  • Makes guard behavior (max-runs, effective-token, timeout steering) independently evolvable without reworking HTTP/WebSocket plumbing.

Implementation approach:

  • Guard extraction
    • containers/api-proxy/guards/max-runs-guard.js
    • containers/api-proxy/guards/effective-token-guard.js
    • containers/api-proxy/guards/timeout-steering.js
  • Utility extraction
    • containers/api-proxy/body-transform.js for body sanitization and steering-message injection.
    • containers/api-proxy/rate-limit.js for rate-limit response handling via an injected checker factory.
  • Transport extraction
    • containers/api-proxy/websocket-proxy.js for WebSocket tunneling logic.
  • Composition root
    • containers/api-proxy/proxy-request.js now composes the extracted modules and retains existing exports used by server.js and tests.
const { sanitizeNullToolCallTypes, injectSteeringMessage } = require('./body-transform');
const { createRateLimitChecker } = require('./rate-limit');
const { createProxyWebSocket } = require('./websocket-proxy');
const { applyEffectiveTokenUsage, getEffectiveTokenBlockState } = require('./guards/effective-token-guard');
const { applyMaxRunsInvocation, getMaxRunsBlockState } = require('./guards/max-runs-guard');

const checkRateLimit = createRateLimitChecker({ limiter, metrics, logRequest, generateRequestId, isValidRequestId });
const proxyWebSocket = createProxyWebSocket({ /* injected deps */ });

Copilot AI changed the title [WIP] Refactor proxy request file into multiple modules Refactor API proxy request path into focused guard and transport modules May 14, 2026
Copilot finished work on behalf of lpcox May 14, 2026 16:09
Copilot AI requested a review from lpcox May 14, 2026 16:09
@lpcox lpcox marked this pull request as ready for review May 14, 2026 16:26
@lpcox lpcox requested a review from Mossaka as a code owner May 14, 2026 16:26
Copilot AI review requested due to automatic review settings May 14, 2026 16:26
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions github-actions Bot mentioned this pull request May 14, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

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 refactors the API proxy request path by extracting guard logic, body transformations, rate limiting, and WebSocket transport into focused modules while keeping proxy-request.js as the composition/root export surface.

Changes:

  • Extracts effective-token, max-runs, and timeout-steering guards.
  • Moves body mutation and rate-limit response handling into reusable modules.
  • Moves WebSocket tunneling logic into a dedicated transport module.
Show a summary per file
File Description
containers/api-proxy/proxy-request.js Composes the extracted modules and preserves shared exports.
containers/api-proxy/body-transform.js Contains request-body sanitization and steering-message injection helpers.
containers/api-proxy/rate-limit.js Provides a factory for rate-limit checks and 429 responses.
containers/api-proxy/websocket-proxy.js Contains WebSocket upgrade validation and tunneling behavior.
containers/api-proxy/guards/effective-token-guard.js Manages effective-token accounting, limits, and token steering state.
containers/api-proxy/guards/max-runs-guard.js Manages max-runs accounting and limit responses.
containers/api-proxy/guards/timeout-steering.js Manages timeout-based steering warnings.

Copilot's findings

Tip

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

  • Files reviewed: 7/7 changed files
  • Comments generated: 1

Comment on lines +16 to +18
const { sanitizeNullToolCallTypes, injectSteeringMessage } = require('./body-transform');
const { createRateLimitChecker } = require('./rate-limit');
const { createProxyWebSocket } = require('./websocket-proxy');
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented May 14, 2026

@copilot address review feedback and fix this failing ci check https://github.com/github/gh-aw-firewall/actions/runs/25870995854/job/76028886971?pr=3159

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot address review feedback and fix this failing ci check https://github.com/github/gh-aw-firewall/actions/runs/25870995854/job/76028886971?pr=3159

Fixed in commit 1757075.

I updated containers/api-proxy/Dockerfile to copy the extracted modules (body-transform.js, rate-limit.js, websocket-proxy.js) and guards/, which resolves the CI failure from job 76028886971 (Cannot find module './body-transform' in the awf-api-proxy container).

Copilot finished work on behalf of lpcox May 14, 2026 16:53
@github-actions
Copy link
Copy Markdown
Contributor

Claude Engine Validation - Smoke Test Results

Test Result
GitHub API (list merged PRs) ❌ FAILED - gh auth issue (HTTP 401)
Playwright (navigate github.com) ✅ PASSED - title contains "GitHub"
File verify (smoke-test-claude-*.txt) ✅ PASSED - file exists with valid content

Summary: 2/3 PASSED - One test failed due to GitHub API authentication issue in the proxy environment.

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

Test Status
GitHub MCP connectivity ❌ (401 Bad credentials)
GitHub.com HTTP connectivity ❌ (template vars not interpolated)
File write/read ❌ (template vars not interpolated)

Overall: FAIL

The pre-step template variables (${{ steps.smoke-data.outputs.* }}) were not substituted, indicating the smoke-data step did not run or output was not passed to this step. GitHub MCP returned 401 Bad credentials.

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK (Offline) Mode

Test Status
GitHub MCP connectivity
GitHub.com HTTP connectivity ✅ (pre-step passed)
File write/read (smoke-test-copilot-byok-25873144391.txt)
BYOK inference (agent → api-proxy → api.githubcopilot.com)

Running in BYOK offline mode (COPILOT_OFFLINE=true) via api-proxy → api.githubcopilot.com

Overall: PASS

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions
Copy link
Copy Markdown
Contributor

Codex Smoke Test

PRs: fix: remove dead re-exports of WrapperConfig component types; fix(entrypoint): preserve setup-* PATH ordering in fallback hostedtoolcache scan
✅ GitHub PR review via public REST; ❌ safeinputs-gh unavailable; ✅ Playwright title; ❌ Tavily unavailable
✅ File write/read; ❌ discussion query unavailable/skipped; ✅ npm ci && npm run build
Overall status: FAIL

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

Gemini Smoke Test Results

  • GitHub MCP Testing: ❌ (Tools not found)
  • GitHub.com Connectivity: ❌ (SSL error 35)
  • 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 All passed ✅ PASS
Node.js execa All passed ✅ PASS
Node.js p-limit All passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Note (Java): Maven's default local repo (~/.m2/repository) was not writable due to directory ownership. Tests were run with -Dmaven.repo.local=/tmp/gh-aw/agent/m2repo as a workaround; all tests passed successfully.

Generated by Build Test Suite for issue #3159 · ● 4M ·

@github-actions
Copy link
Copy Markdown
Contributor

Chroot Smoke Test Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.14.1 v20.20.2
Go go1.22.12 go1.22.12

Overall: ❌ Not all versions match — Python and Node.js differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test: GitHub Actions Services Connectivity

Check Result
Redis PING ❌ Timeout/No response
PostgreSQL pg_isready ❌ No response
PostgreSQL SELECT 1 ❌ Timeout/No response

Overall: FAILhost.docker.internal is unreachable from this environment. Service containers are not accessible.

🔌 Service connectivity validated by Smoke Services

@lpcox lpcox merged commit cf1a4a2 into main May 14, 2026
63 of 68 checks passed
@lpcox lpcox deleted the copilot/refactor-api-proxy-modules branch May 14, 2026 17:42
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.

[Refactoring] Split containers/api-proxy/proxy-request.js into focused modules

3 participants