Skip to content

fix: isolate upstream X-Request-ID per request - #2027

Open
winterfell2021 wants to merge 1 commit into
looplj:unstablefrom
winterfell2021:fix/unique-upstream-request-id
Open

fix: isolate upstream X-Request-ID per request#2027
winterfell2021 wants to merge 1 commit into
looplj:unstablefrom
winterfell2021:fix/unique-upstream-request-id

Conversation

@winterfell2021

Copy link
Copy Markdown

Summary

  • replace a client-provided X-Request-Id on outbound calls with AxonHub's unique per-request ar-* ID
  • keep the ID stable for retry attempts belonging to the same inbound request
  • keep channel header overrides authoritative by applying them after the generated request ID
  • add regression coverage for multiple inbound requests that reuse one client request ID

Problem

AxonHub trace IDs can intentionally span multiple agent calls, while an HTTP request ID must identify one request. The generic inbound-header merge currently forwards X-Request-Id unchanged. If a client reuses that value to group an agent trace, independent outbound calls receive the same request ID.

Downstream gateways that use X-Request-Id for usage idempotency or deduplication can then collapse unrelated requests into one record, mixing models, statuses, token usage, and charges.

AxonHub already generates a unique ar-* request ID for every inbound HTTP request in WithLoggingTracing; it was not previously applied to the outbound provider request.

Fix

Add an outbound raw-request middleware that sets X-Request-Id from AxonHub's request context after inbound headers are merged. Different inbound requests therefore get different downstream IDs even when the client reuses its own value. Retries for one request keep the same ID, and explicit channel header overrides can still replace it.

Verification

  • go test ./...
  • cd llm && go test ./...

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR isolates the upstream request ID for each inbound HTTP request. The main changes are:

  • Adds outbound middleware that replaces client-provided request IDs with AxonHub’s generated ar-* ID.
  • Keeps the generated ID stable across retries for the same request.
  • Applies channel header overrides after the generated request ID.
  • Adds tests for reused client IDs, nil headers, and missing context IDs.

Confidence Score: 5/5

This looks safe to merge.

  • The generated request ID overwrites the propagated client value on normal HTTP request paths.
  • Retry attempts reuse the same request context and therefore keep one stable ID.
  • Channel header overrides remain authoritative as intended.
  • No blocking issue was found in the updated code.

Important Files Changed

Filename Overview
internal/server/orchestrator/orchestrator.go Registers the request ID middleware before channel-specific header overrides.
internal/server/orchestrator/request_id.go Sets the outbound request ID from the inbound request context and initializes headers when needed.
internal/server/orchestrator/request_id_test.go Covers reused client IDs, nil header initialization, and contexts without a request ID.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Inbound request] --> B[Generate unique ar-* ID]
    B --> C[Merge inbound headers]
    C --> D[Set outbound X-Request-Id]
    D --> E[Apply channel overrides]
    E --> F[Send provider request]
    F -->|Retry with same context| C
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart LR
    A[Inbound request] --> B[Generate unique ar-* ID]
    B --> C[Merge inbound headers]
    C --> D[Set outbound X-Request-Id]
    D --> E[Apply channel overrides]
    E --> F[Send provider request]
    F -->|Retry with same context| C
Loading

Reviews (2): Last reviewed commit: "fix: isolate upstream request IDs per re..." | Re-trigger Greptile

@winterfell2021
winterfell2021 force-pushed the fix/unique-upstream-request-id branch from 9d2e725 to d35db06 Compare July 17, 2026 14:33
@looplj

looplj commented Jul 18, 2026

Copy link
Copy Markdown
Owner

这个需要一个配置项

  1. 是否开启
  2. header 是什么

ssxwcz added a commit to ssxwcz/axonhub that referenced this pull request Aug 31, 2026
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.

2 participants