Skip to content

fix(privacy): resolve PII feature flag correctly and fix PII response sanitization in streaming SSE requests - #3021

Merged
diegosouzapw merged 47 commits into
cheaper-inference:release/v3.8.8from
dangeReis:fix/pii-streaming-sanitization
Jun 1, 2026
Merged

diegosouzapw merged 47 commits into
cheaper-inference:release/v3.8.8from
dangeReis:fix/pii-streaming-sanitization

Conversation

@dangeReis

Copy link
Copy Markdown
Contributor

Closes #3020

See issue description in #3020 for a detailed explanation of changes.

branben and others added 23 commits May 30, 2026 21:17
… scopes to all dynamic tool definitions (cheaper-inference#2958)

Integrated into release/v3.8.8
…ombo target's providerId over model-inferred provider (cheaper-inference#2946)

Integrated into release/v3.8.8
Full SOLO remote-agent integration against solo.trae.ai's reverse-engineered
API (upgrades the previous import_token stub).

- open-sse/executors/trae.ts: streaming executor for the solo_agent_remote API
  (POST /chat_sessions + GET /events SSE -> OpenAI chat.completions), accumulating
  plan_item thoughts and mapping token_usage. Headless Cloud-IDE-JWT refresh via
  the ExchangeToken endpoint.
- Session mode via model id: `trae/work` runs the fast work-mode auto agent;
  `trae/auto` and named models (gpt-5.4, kimi-k2.5, gemini-3.1-pro, ...) run in
  code mode.
- Provider registry entry (models + 272k context) and executor wiring.
- Two credential paths: browser /authorize loopback callback (captures the JWT +
  long-lived refresh token) and manual Cloud-IDE-JWT paste via
  POST /api/oauth/trae/import (Zod-validated).
- TraeAuthModal dashboard UI wired into the provider detail page.
- mapTokens/providerSpecificData carry the SOLO common_params identity fields.
- Tests: executor (stream/non-stream/error/refresh/work-mode + callback parser)
  and updated oauth-trae provider tests.
…stry

Root cause: Node.js process crashes with OOM (JavaScript heap out of memory)
within 5 minutes of intensive use. Heap exhausted at ~250MB.

Three fixes targeting the memory leak sources identified during investigation:

1. comboMetrics.ts — Add eviction + TTL for metrics/shadowMetrics Maps
   - MAX_METRICS_ENTRIES = 500 (LRU eviction via lastUsedAt)
   - METRICS_TTL_MS = 1 hour
   - Cleanup interval every 5 minutes (unref'd)
   - Size-cap checks in recordComboRequest, recordComboShadowRequest, recordComboIntent

2. usage.ts — Proactive TTL purging for 6 passive subscription caches
   - SUB_CACHE_TTL_MS = 10 minutes
   - Cleanup interval every 5 minutes (unref'd)
   - Purges: geminiCliSubCache, antigravitySubCache, antigravityAvailableModelsCache,
     antigravityCreditProbeCache
   - Inflight Maps left alone (self-clean on Promise resolution)

3. providerRegistry.ts — Lazy Proxy for 212 provider entries
   - REGISTRY renamed to _REGISTRY_EAGER, wrapped in lazy Proxy
   - Individual entries materialized on first access only (_registryCache Map)
   - _byAlias, _unsupportedParamsMap, _passthroughProviderIds all made lazy
   - getRegisteredProviders() returns pre-computed _registryKeys (no eager iteration)

Also noted: Dockerfile hardcodes --max-old-space-size=256 (too low for production).
.env.example documents OMNIROUTE_MEMORY_MB but no script reads it — entrypoint
should be updated separately to respect this setting.

TypeScript: zero new errors introduced (pre-existing mcp-server/server.ts errors
confirmed on main branch)
…verride

Dockerfile: OMNIROUTE_MEMORY_MB=1024 (was hardcoded 256MB).
NODE_OPTIONS now references OMNIROUTE_MEMORY_MB so users can
override via docker run -e OMNIROUTE_MEMORY_MB=2048.

check-permissions.sh: entrypoint reads OMNIROUTE_MEMORY_MB and
builds NODE_OPTIONS dynamically. This was documented in .env.example
but never actually implemented — the entrypoint just did exec
without processing the variable.

Combined with the first commit's cache eviction fixes, this should
prevent the OOM crashes that killed the process within 5 minutes
of intensive use.
1. check-permissions.sh: swap NODE_OPTIONS flag order so runtime
   OMNIROUTE_MEMORY_MB override wins (last flag takes precedence)

2. comboMetrics.ts: evictOldestMetric(targetMap) now accepts the
   target map as parameter; cleanup timer iterates BOTH metrics
   AND shadowMetrics; null lastUsedAt falls back to Date.now()
   instead of epoch 0 (prevents premature eviction of intent-only
   entries)

3. providerRegistry.ts: remove Proxy wrapper — adds CPU/complexity
   overhead with zero memory savings since _REGISTRY_EAGER is
   already fully allocated and generator functions iterate all
   entries at startup. Simple re-export instead.

4. usage.ts: use per-cache TTL constants in cleanup timer
   (ANTIGRAVITY_MODELS_CACHE_TTL_MS=1min, others=5min) instead of
   single 10min SUB_CACHE_TTL_MS for all caches.

5. Add 18 unit tests for comboMetrics memory management covering:
   basic CRUD, shadow metrics, intent tracking, eviction at capacity,
   strategy tracking, and reset operations.
Signed-off-by: Xiangzhe <xiangzhedev@gmail.com>
Translates ~267 previously-English or __MISSING__ entries in the
Ukrainian locale, focused on the most user-visible surfaces:

- sidebar: all menu items, section labels, page subtitles
- header: page titles and descriptions
- apiManager: 3 __MISSING__ endpoint-restriction keys
- common: high-traffic UI labels (buttons, statuses, common nouns)
- settings: 7 newly-added Home-page quota/topology keys

Key parity with en.json restored: 0 missing, 0 extra.
…-ui-menu

fix(i18n): translate Ukrainian (uk-UA) menu and UI strings
…w-cn-endpoint-selector

feat(providers): add SiliconFlow endpoint selector
…anup, scripts)

- Restrict the /authorize postMessage and the modal listener to the loopback
  origin pair (localhost + 127.0.0.1) instead of "*"/single-origin. The dashboard
  runs on localhost while Trae forces the callback onto 127.0.0.1, so a single
  window.location.origin target silently dropped the success message (popup never
  closed). Addresses CWE-359 without breaking the cross-loopback flow.
- TraeExecutor: cancel the SSE reader on completion, abort upfront when the caller
  signal is already aborted, and accept string elements in array message content.
- Move ad-hoc dev scripts to scripts/ad-hoc/ per the repo style guide.
…provider

feat(oauth): add Trae SOLO provider
…ory-leak-caches

fix(oom): prevent unbounded memory growth causing heap OOM crashes
@dangeReis
dangeReis requested a review from diegosouzapw as a code owner May 31, 2026 22:16

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces streaming PII response sanitization by adding a new SSE text transformation utility (createSseTextTransform) and integrating it into the chat core stream handler. The PII sanitizer configuration was also updated to resolve settings via feature flags instead of directly reading environment variables. Comprehensive unit tests were added to verify the new stream transformations and feature flag behavior. Feedback on the changes focuses on improving the robustness of the SSE parser, including trimming segments before JSON detection, adding null-safe checks for choices, and ensuring empty string arguments are not incorrectly skipped during processing.

Comment thread src/lib/sseTextTransform.ts Outdated
Comment thread src/lib/sseTextTransform.ts Outdated
Comment thread src/lib/sseTextTransform.ts Outdated
Comment thread src/lib/sseTextTransform.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 878eb447ae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/streamingPiiTransform.ts Outdated
Ruslan Sivak added 2 commits May 31, 2026 18:24
@dangeReis

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a streaming PII sanitization layer for Server-Sent Events (SSE) by implementing a generic SSE text transformer and a sliding-window PII transform, integrated with feature flags. Feedback on these changes highlights a critical correctness bug where up to 40 characters of buffered text can be lost on stream flush if the final chunk is a metadata, tool call, or reasoning block. Additionally, the review points out two violations of the repository style guide regarding silently swallowing errors in SSE streams, and notes a performance concern where the fixed window size introduces streaming latency.

Comment thread src/lib/streamingPiiTransform.ts Outdated
Comment thread src/lib/sseTextTransform.ts Outdated
Comment thread src/lib/sseTextTransform.ts
Comment thread src/lib/streamingPiiTransform.ts Outdated

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a robust PII response sanitization layer for streaming and non-streaming LLM responses, integrating it into the SSE pipeline with support for multiple formats (OpenAI, Claude, Gemini). It includes sliding-window sanitization, checksum validations, and extensive unit tests. The reviewer feedback highlights a few issues: the test script test_pii_vulns.ts is incorrectly placed in the project root, violating the repository style guide; the fallback logic in getMode fails to map explicit false values to the 'off' mode; onFlush can be called redundantly in sseTextTransform.ts upon receiving the [DONE] sentinel; and there is a discrepancy in adversarialPii.test.ts regarding whether the minimum window size is clamped to 80 or 200.

Comment thread test_pii_vulns.ts Outdated
Comment thread src/lib/piiSanitizer.ts
Comment thread src/lib/sseTextTransform.ts
Comment thread tests/unit/adversarialPii.test.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d0e4bc714

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/sseTextTransform.ts Outdated
@dangeReis

Copy link
Copy Markdown
Contributor Author

@codex review

@dangeReis

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f88466b53

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/sseTextTransform.ts
Comment thread src/lib/piiSanitizer.ts
@dangeReis

Copy link
Copy Markdown
Contributor Author

@codex review

@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.8.8 June 1, 2026 10:37
…eaming-sanitization

# Conflicts:
#	.env.example
#	.source/browser.ts
#	.source/server.ts
#	docs/frameworks/MCP-SERVER.md
#	open-sse/handlers/chatCore.ts
#	open-sse/mcp-server/server.ts
#	src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx
#	src/i18n/messages/uk-UA.json
#	tests/unit/api-manager-page-static.test.ts
@diegosouzapw
diegosouzapw merged commit e11366b into cheaper-inference:release/v3.8.8 Jun 1, 2026
2 of 3 checks passed
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Merged into release/v3.8.8 🎉 Thanks @dangeReis! Excellent privacy fix. I pushed a few review fixes to your branch: sanitized the block-mode/fallback error paths so they don't leak detail into stream errors (Hard Rule #12), replaced the as any cast with a typed one, fixed a string===boolean typecheck error, and dropped the auto-generated .source/* files. typecheck + PII tests green. Ships next release.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23b2a8ae28

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/sseTextTransform.ts
diegosouzapw added a commit to oyi77/OmniRoute that referenced this pull request Jun 1, 2026
…k-mode test

(a) adversarialPii — sk_ key: restore strict assertion that sk_… keys ARE redacted
    (regex /(?:sk|pk|api|key|token)[_-][a-zA-Z0-9]{20,}/ matches underscore too;
    the PR's comment "only sk- with hyphen" was wrong).

(b) adversarialPii — VULN-004 circular/SSN: require exact "[CIRCULAR_REFERENCE_REDACTED]"
    sentinel (not lowercase .includes("circular")) and require SSN is "[SSN_REDACTED]"
    (never raw passthrough).

(c) t23-t24-fallback-resilience — T24 wait-log: restore the assert that a debug
    "Waiting …ms before fallback" log IS emitted. The cooldown comes from
    checkFallbackError (5 s for plain 503), not the circuit breaker — the PR's
    claim "mock CB has no cooldown → no wait" was incorrect.

(d) piiReproduction — THEORY-004 Scenarios A & B: replace typeof=string no-ops
    with meaningful assertions that document the post-cheaper-inference#3021 correct behavior:
    Scenario A must NOT wrap raw text in a {"choices":…} envelope; Scenario B
    must emit the full content (split by window, not silently lost).

(e) adversarialPii — block-mode test env leak: the finally block was deleting
    PII_RESPONSE_SANITIZATION / MODE from process.env, wiping the keys set by
    the outer test scope. Changed to save-and-restore so subsequent subtests
    (premature-redaction, VULN-004) run with PII enabled.

chat-context-relay masking (e) was investigated and found to be a legitimate
alignment: the second test exercises the emergency-fallback path (comboStrategy=null)
which correctly does NOT inject or consume handoffs. Assertions match real behavior.
diegosouzapw added a commit that referenced this pull request Jun 1, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (#2859/#3022/#3032),
  page redesigns (#2827/#2839/#2847/#2849/#2869/#2873), and fixes #2960/#2973/#2984/
  #3021/#3029/#3031/#3035/#3036/#3037/#3039/#3043/#3028; folded #2978/#2988/#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
@diegosouzapw diegosouzapw mentioned this pull request Jun 2, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
… sanitization in streaming SSE requests (cheaper-inference#3021)

Integrated into release/v3.8.8. Fixes the PII feature-flag resolution + adds streaming-aware SSE PII sanitization (rolling-window transform, obfuscation-hardened regexes, Luhn/CPF/CNPJ checks). Applied review fixes: block-mode + fallback errors no longer leak pattern types / upstream err.message into stream errors (Hard Rule cheaper-inference#12); typed the createPiiTransform cast (no any); fixed a string===boolean type error; dropped the generated .source/* files. Thanks @dangeReis!
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032),
  page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/
  cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
… sanitization in streaming SSE requests (cheaper-inference#3021)

Integrated into release/v3.8.8. Fixes the PII feature-flag resolution + adds streaming-aware SSE PII sanitization (rolling-window transform, obfuscation-hardened regexes, Luhn/CPF/CNPJ checks). Applied review fixes: block-mode + fallback errors no longer leak pattern types / upstream err.message into stream errors (Hard Rule cheaper-inference#12); typed the createPiiTransform cast (no any); fixed a string===boolean type error; dropped the generated .source/* files. Thanks @dangeReis!
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032),
  page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/
  cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
… sanitization in streaming SSE requests (cheaper-inference#3021)

Integrated into release/v3.8.8. Fixes the PII feature-flag resolution + adds streaming-aware SSE PII sanitization (rolling-window transform, obfuscation-hardened regexes, Luhn/CPF/CNPJ checks). Applied review fixes: block-mode + fallback errors no longer leak pattern types / upstream err.message into stream errors (Hard Rule cheaper-inference#12); typed the createPiiTransform cast (no any); fixed a string===boolean type error; dropped the generated .source/* files. Thanks @dangeReis!
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032),
  page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/
  cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
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.

[BUG]: PII sanitization feature flag bypass and failure on streaming responses