LibreChat/packages/api/src
Danny Avila 8969034ad1
fix: Strip remaining unsupported JSON Schema keywords for Gemini MCP tools (#13850)
*  fix: Strip remaining unsupported JSON Schema keywords for Gemini MCP tools

Gemini's FunctionDeclaration.parameters schema rejects more JSON Schema
keywords than sanitizeGeminiSchema previously stripped. MCP tools shipping
examples/readOnly/multipleOf/uniqueItems/prefixItems/etc. still 400 with
`Unknown name "<key>"`, the same class as #13623 (exclusiveMinimum).

Verified live against gemini-2.5-flash and gemini-3.5-flash: each added
keyword is rejected through `parameters`, and @langchain/google-genai only
removes additionalProperties/$schema, so they must be stripped here.

*  refactor: Make Gemini strip-list fully live-verified; preserve `default`

Probed every candidate keyword against both the live Gemini API
(gemini-2.5-flash, gemini-3.5-flash) and Vertex AI. Confirmed the inferred
siblings (dependencies/dependentSchemas/contentSchema) are rejected, so they
stay. Dropped `default`: it is part of Gemini's Schema and is accepted by both
the Gemini API and Vertex (no documented reason for its removal in #13623), so
it is now preserved instead of stripped.

*  fix: Preserve `default` data and synthesize array `items` (Codex P2s)

Addresses two Codex findings on the strip-list rework:

- `default` is now copied verbatim instead of recursed, so object/array default
  values (e.g. `{ id: 'abc', readOnly: true }`) keep ordinary data keys that the
  schema-recursion would otherwise strip.
- `prefixItems` is dropped but its first member is synthesized into `items`, since
  Gemini's API requires `items` on every array (live: itemless array => 400; the
  synthesized `{type:array, items:{...}}` => 200 on Gemini 2.5/3.5 and Vertex).

Third finding (patternProperties -> empty object) not actioned: live probing shows
`{type:'object'}` with no properties is accepted by both the Gemini API and Vertex.

*  fix: Treat boolean/tuple array `items` as missing (Codex P2)

The Draft 2020 tuple form `prefixItems: [...], items: false` slipped through: the
`'items' in collapsed` check treated boolean `false` as a real item schema, so no
fallback was synthesized and `items: false` was emitted — which Gemini rejects
(live: `items: false`/`true` => 400 "Invalid value").

Now `items` is only kept when it is a schema object; boolean and tuple-array
(`items: [...]`) forms are dropped, a `prefixItems` member is synthesized when
present, and any array still missing `items` falls back to `{}` (verified accepted
by the Gemini API and Vertex). Adds an `isObjectSchema` guard + tests.
2026-06-19 13:14:47 -04:00
..
acl 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
actions 🔀 fix: Reconcile Agent Action Credential Merges (#13559) 2026-06-06 15:09:58 -04:00
admin 📒 feat: Audit Log Backend for SystemGrant Assign and Revoke Events (#13087) 2026-06-18 15:42:33 -04:00
agents 🦜 refactor: Use path for Read/Write/Edit/Create File Tools (#13834) 2026-06-18 14:44:51 -04:00
apiKeys ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
app 📈 fix: Isolate RUM Telemetry Proxy Auth from App Auth (#13765) 2026-06-15 12:49:44 -04:00
artifacts 🪡 fix: Artifact Edit Saves (#13358) 2026-05-27 22:03:42 -07:00
auth 🌐 fix: Centralize Outbound Proxy Handling (#13726) 2026-06-14 10:47:49 -04:00
cache 🚰 ci: Close Leaked Redis Clients in Cache Integration Tests (#13649) 2026-06-10 08:59:13 -04:00
cdn ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
cluster ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
crypto
db 🗂️ feat: Add Private Chat Projects (#13467) 2026-06-03 15:29:18 -04:00
endpoints 🕐 feat: Add promptCacheTtl model parameter for 1h/5m cache duration (#13835) 2026-06-18 16:36:43 -04:00
files 🌐 fix: Centralize Outbound Proxy Handling (#13726) 2026-06-14 10:47:49 -04:00
flow 🤫 refactor: Silent MCP OAuth Refresh on Mid-Session 401 (#13369) 2026-06-10 13:12:42 -04:00
html ⚙️ refactor: lazy-load React Query Devtools (#13639) 2026-06-10 13:06:20 -04:00
langfuse 📋 refactor: Attach Message Context to Langfuse Feedback Scores (#13604) 2026-06-08 15:54:01 -04:00
mcp fix: Strip remaining unsupported JSON Schema keywords for Gemini MCP tools (#13850) 2026-06-19 13:14:47 -04:00
memory 🧠 fix: Bound Memory Agent Input (#13606) 2026-06-09 14:38:21 -04:00
middleware 🌐 fix: Centralize Outbound Proxy Handling (#13726) 2026-06-14 10:47:49 -04:00
modelSpecs 💬 feat: Conversation Starters for Model Specs (#13710) 2026-06-13 11:38:49 -04:00
oauth ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
projects ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
prompts ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
rum 📈 fix: Isolate RUM Telemetry Proxy Auth from App Auth (#13765) 2026-06-15 12:49:44 -04:00
shared-links 🔗 feat: Add Granular Access Control to Shared Links via ACL System (#13051) 2026-06-03 14:17:17 -04:00
skills 🏘️ fix: Scope Skill Sync Status (#13771) 2026-06-15 15:23:49 -04:00
storage ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00
stream 🪙 refactor: Reconcile Context Gauge to Actual Provider Tokens (#13780) 2026-06-16 11:05:44 -04:00
telemetry 📡 refactor: Gate Noisy Redis OTEL Instrumentation (#13764) 2026-06-15 12:48:20 -04:00
tools fix: Sanitize MCP Tool Schemas for Gemini/Vertex Compatibility (#13623) 2026-06-09 14:16:25 -04:00
types 🕐 feat: Add promptCacheTtl model parameter for 1h/5m cache duration (#13835) 2026-06-18 16:36:43 -04:00
utils 📨 feat: Custom Headers on Built-in Provider Endpoints (#13742) 2026-06-14 17:02:04 -04:00
web 🛟 refactor: Gracefully Skip Unavailable Web Search Rerankers (#13191) 2026-05-19 09:48:12 -04:00
index.ts 🪢 fix: Tie MCP Cleanup To Resumable Runs (#13769) 2026-06-15 15:26:03 -04:00
telemetry.ts ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00