Repository navigation
fix(privacy): resolve PII feature flag correctly and fix PII response sanitization in streaming SSE requests - #3021
Conversation
…ab, and 20 tests (cheaper-inference#2959) Integrated into release/v3.8.8
… scopes to all dynamic tool definitions (cheaper-inference#2958) Integrated into release/v3.8.8
…heaper-inference#2957) Integrated into release/v3.8.8
…mizations (cheaper-inference#2951) Integrated into release/v3.8.8
…ombo target's providerId over model-inferred provider (cheaper-inference#2946) Integrated into release/v3.8.8
…native Claude OAuth (cheaper-inference#2943) Integrated into release/v3.8.8
Integrated into release/v3.8.8
…#2938) Integrated into release/v3.8.8
Integrated into release/v3.8.8
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
… sanitization in streaming SSE requests
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
💡 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".
…carry-over buffering and template-based onFlush serialization
…g PII sanitization
|
/gemini review |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
💡 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".
…rnings in CLAUDE.md
|
@codex review |
|
@codex review |
There was a problem hiding this comment.
💡 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".
|
@codex review |
…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
… getMode (TS2367)
e11366b
into
cheaper-inference:release/v3.8.8
|
Merged into |
There was a problem hiding this comment.
💡 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".
…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.
…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)
… 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!
…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)
… 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!
…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)
… 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!
…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)
Closes #3020
See issue description in #3020 for a detailed explanation of changes.