Skip to content

Fix AI provider header redaction#6650

Merged
IMax153 merged 4 commits into
mainfrom
fix/ai-provider-header-redaction
Jul 26, 2026
Merged

Fix AI provider header redaction#6650
IMax153 merged 4 commits into
mainfrom
fix/ai-provider-header-redaction

Conversation

@IMax153

@IMax153 IMax153 commented Jul 26, 2026

Copy link
Copy Markdown
Member

Summary

  • apply provider-specific header redaction while OpenAI, OpenAI-compatible, and Anthropic requests and error mapping execute
  • refactor OpenAI client tests around shared JSON/SSE response mocks and captured requests
  • add focused Anthropic and OpenRouter status-error redaction coverage

Testing

  • pnpm test packages/ai/openai-compat/test/OpenAiClient.test.ts
  • pnpm test packages/ai/openai/test/OpenAiClient.test.ts
  • pnpm test packages/ai/anthropic/test/AnthropicClient.test.ts packages/ai/anthropic/test/AnthropicLanguageModel.test.ts
  • pnpm test packages/ai/openrouter/test/OpenRouterClient.test.ts packages/ai/openrouter/test/OpenRouterLanguageModel.test.ts
  • targeted package typechecks and oxlint

Summary by CodeRabbit

  • Bug Fixes
    • Improved sensitive-header redaction so API keys and OpenAI organization/project headers are no longer exposed in client error context.
    • Ensures redaction is applied consistently across Anthropic, OpenAI, OpenAI compatibility, and OpenRouter for non-streaming, streaming, and embeddings requests.
  • Tests
    • Added/updated client test coverage to verify outgoing request headers and error redaction, including SSE streaming and embeddings flows.

@github-project-automation github-project-automation Bot moved this to Discussion Ongoing in PR Backlog Jul 26, 2026
@changeset-bot

changeset-bot Bot commented Jul 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b1aac18

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 28 packages
Name Type
@effect/ai-anthropic Patch
@effect/ai-openai Patch
@effect/ai-openai-compat Patch
effect Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/vitest Patch
@effect/ai-openrouter Patch
@effect/atom-react Patch
@effect/atom-solid Patch
@effect/atom-vue Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-pglite Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/docgen Patch
@effect/openapi-generator Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@effect-slopcop effect-slopcop Bot added 4.0 bug Something isn't working labels Jul 26, 2026
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 81c34890-4b40-485a-a6d5-380cac6f09f9

📥 Commits

Reviewing files that changed from the base of the PR and between b1ab5d0 and b1aac18.

📒 Files selected for processing (1)
  • packages/ai/openai/test/OpenAiClient.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ai/openai/test/OpenAiClient.test.ts

📝 Walkthrough

Walkthrough

Provider clients now scope sensitive header names during request execution so mapped HTTP errors redact API keys and OpenAI organization/project headers. Tests add mock layers and verify redaction, request behavior, streaming, embeddings, and error mappings across Anthropic, OpenAI, OpenAI-compatible, and OpenRouter clients.

Changes

Provider header redaction

Layer / File(s) Summary
Anthropic request redaction
packages/ai/anthropic/src/AnthropicClient.ts, packages/ai/anthropic/test/AnthropicClient.test.ts
Anthropic message and streaming requests apply API-key redaction through Headers.CurrentRedactedNames; tests verify redacted error-context headers using mocked HTTP responses.
OpenAI request redaction
packages/ai/openai/src/*, packages/ai/openai-compat/src/*, packages/ai/openai/test/*, packages/ai/openai-compat/test/*
OpenAI and compatible response, streaming, and embedding requests scope organization/project header redaction while tests use shared mock layers for request assertions, streaming, and error mapping.
OpenRouter coverage and release metadata
packages/ai/openrouter/test/OpenRouterClient.test.ts, .changeset/*redaction.md
OpenRouter tests verify authorization redaction, and changesets record patch releases for the affected provider packages.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • Effect-TS/effect#6548: Introduces and applies the shared OpenAI header-redaction approach covered by this change.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/ai/openai-compat/test/OpenAiClient.test.ts (1)

257-263: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Assert the error shape instead of falling back to Headers.empty.

If the reason isn't InvalidRequestError, the three assertions fail with "undefined" !== "<redacted>", which hides the real cause. The Anthropic and OpenRouter variants narrow explicitly first — worth matching for a clearer failure message.

♻️ Proposed refactor
-        const headers = result.reason._tag === "InvalidRequestError"
-          ? result.reason.http?.request.headers ?? Headers.empty
-          : Headers.empty
-
+        assert.strictEqual(result.reason._tag, "InvalidRequestError")
+        if (result.reason._tag !== "InvalidRequestError" || result.reason.http === undefined) {
+          return yield* Effect.die(new Error("Expected InvalidRequestError with HTTP context"))
+        }
+        const headers = result.reason.http.request.headers
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai/openai-compat/test/OpenAiClient.test.ts` around lines 257 - 263,
Update the test around the result.reason header assertions to explicitly narrow
or assert that result.reason is an InvalidRequestError before accessing
http.request.headers. Remove the Headers.empty fallback, then assert the
redacted authorization, openai-organization, and openai-project headers from the
narrowed error so unexpected error shapes fail clearly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ai/openai/test/OpenAiClient.test.ts`:
- Around line 551-558: Type inference for the HttpClient.makeWith preprocess is
too broad in both test harnesses. In
packages/ai/openai/test/OpenAiClient.test.ts lines 551-558, replace the
preprocess lambda with the typed Effect.succeed as
HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>; make
the same change at packages/ai/openrouter/test/OpenRouterClient.test.ts lines
63-70 and add the HttpClientError type import from effect/unstable/http.
- Around line 523-535: Update the MockResponse type’s body and events payload
declarations to accept the Generated.Response.Encoded values returned by
makeResponseBody, rather than restricting them to Schema.Json. Preserve the
existing Json and SSE mock structure and status/header fields.

---

Nitpick comments:
In `@packages/ai/openai-compat/test/OpenAiClient.test.ts`:
- Around line 257-263: Update the test around the result.reason header
assertions to explicitly narrow or assert that result.reason is an
InvalidRequestError before accessing http.request.headers. Remove the
Headers.empty fallback, then assert the redacted authorization,
openai-organization, and openai-project headers from the narrowed error so
unexpected error shapes fail clearly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 31e9dbf2-fef4-4877-87a1-c44c7805d180

📥 Commits

Reviewing files that changed from the base of the PR and between 5e92216 and 63e4c68.

📒 Files selected for processing (10)
  • .changeset/fix-anthropic-header-redaction.md
  • .changeset/fix-openai-header-redaction.md
  • packages/ai/anthropic/src/AnthropicClient.ts
  • packages/ai/anthropic/test/AnthropicClient.test.ts
  • packages/ai/openai-compat/src/OpenAiClient.ts
  • packages/ai/openai-compat/test/OpenAiClient.test.ts
  • packages/ai/openai/src/OpenAiClient.ts
  • packages/ai/openai/src/OpenAiClientGenerated.ts
  • packages/ai/openai/test/OpenAiClient.test.ts
  • packages/ai/openrouter/test/OpenRouterClient.test.ts

Comment thread packages/ai/openai/test/OpenAiClient.test.ts
Comment on lines +551 to +558
const httpClient = HttpClient.makeWith(
Effect.fnUntraced(function*(requestEffect) {
const request = yield* requestEffect
capturedRequests.push(request)
return makeResponse(request, mock.response)
}),
(request) => Effect.succeed(request)
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Untyped HttpClient.makeWith preprocess breaks the Types check in two harnesses. Passing (request) => Effect.succeed(request) leaves E/R uninferred, so makeWith yields HttpClient.With<unknown, unknown>, which is rejected by Context.make(HttpClient.HttpClient, ...). The Anthropic and OpenAI-compat harnesses avoid this by annotating the preprocess.

  • packages/ai/openai/test/OpenAiClient.test.ts#L551-L558: replace the lambda with Effect.succeed as HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never> (fixes the CI error at Line 564).
  • packages/ai/openrouter/test/OpenRouterClient.test.ts#L63-L70: apply the same annotation and add the type HttpClientError import from effect/unstable/http (fixes the CI error at Line 76).
📍 Affects 2 files
  • packages/ai/openai/test/OpenAiClient.test.ts#L551-L558 (this comment)
  • packages/ai/openrouter/test/OpenRouterClient.test.ts#L63-L70
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai/openai/test/OpenAiClient.test.ts` around lines 551 - 558, Type
inference for the HttpClient.makeWith preprocess is too broad in both test
harnesses. In packages/ai/openai/test/OpenAiClient.test.ts lines 551-558,
replace the preprocess lambda with the typed Effect.succeed as
HttpClient.HttpClient.Preprocess<HttpClientError.HttpClientError, never>; make
the same change at packages/ai/openrouter/test/OpenRouterClient.test.ts lines
63-70 and add the HttpClientError type import from effect/unstable/http.

Source: Pipeline failures

@github-project-automation github-project-automation Bot moved this from Discussion Ongoing to Waiting on Author in PR Backlog Jul 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Analysis

File Name Current Size Previous Size Difference
basic.ts 6.60 KB 6.60 KB 0.00 KB (0.00%)
batching.ts 9.36 KB 9.36 KB 0.00 KB (0.00%)
brand.ts 6.25 KB 6.25 KB 0.00 KB (0.00%)
cache.ts 10.07 KB 10.07 KB 0.00 KB (0.00%)
config.ts 19.17 KB 19.17 KB 0.00 KB (0.00%)
differ.ts 18.39 KB 18.39 KB 0.00 KB (0.00%)
http-client.ts 20.75 KB 20.75 KB 0.00 KB (0.00%)
logger.ts 10.25 KB 10.25 KB 0.00 KB (0.00%)
metric.ts 8.51 KB 8.51 KB 0.00 KB (0.00%)
optic.ts 7.41 KB 7.41 KB 0.00 KB (0.00%)
pubsub.ts 14.19 KB 14.19 KB 0.00 KB (0.00%)
queue.ts 11.05 KB 11.05 KB 0.00 KB (0.00%)
schedule.ts 10.24 KB 10.24 KB 0.00 KB (0.00%)
schema-class.ts 18.12 KB 18.12 KB 0.00 KB (0.00%)
schema-fromJsonSchemaDocument.ts 27.97 KB 27.97 KB 0.00 KB (0.00%)
schema-representation-roundtrip.ts 24.30 KB 24.30 KB 0.00 KB (0.00%)
schema-string-transformation.ts 12.65 KB 12.65 KB 0.00 KB (0.00%)
schema-string.ts 10.31 KB 10.31 KB 0.00 KB (0.00%)
schema-template-literal.ts 14.45 KB 14.45 KB 0.00 KB (0.00%)
schema-toArbitraryLazy.ts 20.90 KB 20.90 KB 0.00 KB (0.00%)
schema-toCodeDocument.ts 23.33 KB 23.33 KB 0.00 KB (0.00%)
schema-toCodecJson.ts 18.29 KB 18.29 KB 0.00 KB (0.00%)
schema-toEquivalence.ts 17.96 KB 17.96 KB 0.00 KB (0.00%)
schema-toFormatter.ts 17.84 KB 17.84 KB 0.00 KB (0.00%)
schema-toJsonSchemaDocument.ts 21.48 KB 21.48 KB 0.00 KB (0.00%)
schema-toRepresentation.ts 18.52 KB 18.52 KB 0.00 KB (0.00%)
schema.ts 17.39 KB 17.39 KB 0.00 KB (0.00%)
stm.ts 12.02 KB 12.02 KB 0.00 KB (0.00%)
stream.ts 9.32 KB 9.32 KB 0.00 KB (0.00%)

@IMax153 IMax153 linked an issue Jul 26, 2026 that may be closed by this pull request
@IMax153
IMax153 enabled auto-merge (squash) July 26, 2026 17:32
@IMax153
IMax153 disabled auto-merge July 26, 2026 17:32
@IMax153
IMax153 merged commit acd385e into main Jul 26, 2026
15 checks passed
@IMax153
IMax153 deleted the fix/ai-provider-header-redaction branch July 26, 2026 17:32
@github-project-automation github-project-automation Bot moved this from Waiting on Author to Done in PR Backlog Jul 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4.0 bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

AI provider specific headers aren't correctly redacted

1 participant