LibreChat/packages/api
Danny Avila 6c36d8038c
fix: Sanitize MCP Tool Schemas for Gemini/Vertex Compatibility (#13623)
* 🧰 fix: Flatten union schemas for Gemini/Vertex MCP tool compatibility

`@langchain/google-common`'s `zod_to_gemini_parameters` throws "Gemini cannot
handle union types" on any genuine `anyOf`/`oneOf` (e.g. discriminated unions),
so MCP tools shipping union-typed schemas crash on the Google endpoint while
working fine on OpenAI/Claude.

Add `flattenJsonSchemaUnions` (packages/api) to collapse unions to their first
non-null member and multi-entry `type` arrays to a single nullable type, and
apply it in `createToolInstance`'s existing `isGoogle` branch so only the
Google/Vertex path is affected. Lossy by design, mirroring the existing
empty-object fallback.

Closes #13612

* 🩹 fix: Address Codex review — preserve fields, strip null enums, cover definitions path

- Preserve parent-level `properties`/`required` when collapsing a union: merge the
  chosen branch into the parent instead of overwriting, so args declared outside the
  union (e.g. always-required fields) still reach Gemini.
- Drop the `null` member from `enum` when a union/type-array makes a field nullable,
  keeping Gemini's required homogeneous-enum invariant.
- Propagate the Google-flattened schema to the definitions/deferred-tool path:
  thread `provider` into `loadToolDefinitions` and flatten there, and store the
  flattened schema on `mcpJsonSchema` so `extractMCPToolDefinition` no longer emits
  raw unions on Google/Vertex.

* 🎨 style: Sort imports in tools/definitions per import-order check

*  feat: Broaden union flatten into a full Gemini schema sanitizer

The union flatten alone wasn't enough — real GitHub MCP tools on Gemini also 400
with `Invalid value ... (TYPE_STRING), true`, because Gemini's function-calling
Schema (https://ai.google.dev/api/caching#Schema) accepts only a restricted JSON
Schema subset, and `enum` is `Type.STRING`-only.

Rename `flattenJsonSchemaUnions` → `sanitizeGeminiSchema` and broaden it (one pass,
Gemini-gated) to cover the documented subset:

- Keep only string `enum` values; drop the keyword for non-string types (fixes the
  reported boolean-enum 400, incl. boolean `const` normalized to `enum: [true]`).
- `const` → single-value string enum, or drop if non-string.
- Merge `allOf` intersections; fold `exclusiveMinimum`/`exclusiveMaximum` into
  `minimum`/`maximum`.
- Strip unsupported keywords: `additionalProperties`, `default`, `$schema`, `$id`.
- (Existing) collapse `anyOf`/`oneOf`, multi-entry `type` arrays, nullable.

Grounded in Google's Schema docs rather than reverse-engineered from 400s. Verified
end-to-end against the real `@langchain/google-common` converter. Complements
danny-avila/agents#232 (langchain bump), which defers schema flattening to LibreChat.

* 🩹 fix: Gate enum retention on the effective (collapsed) type

Codex review: a mixed-type enum like `type: ['integer','string'], enum: [1,'auto']`
collapsed the type to `integer` but still kept the string value `'auto'`, yielding
`{type:'integer', enum:['auto']}` — a non-string type with an enum, which Gemini
rejects. Keep `enum` only when the effective collapsed type is string (or unset),
and stamp `type: 'string'` on a surviving typeless enum (e.g. a string `const`
discriminator) so it satisfies Gemini's Type.STRING enum requirement.
2026-06-09 14:16:25 -04:00
..
src fix: Sanitize MCP Tool Schemas for Gemini/Vertex Compatibility (#13623) 2026-06-09 14:16:25 -04:00
types 🔬 ci: Add TypeScript Type Checks to Backend Workflow and Fix All Type Errors (#12451) 2026-03-28 21:06:39 -04:00
.gitignore
babel.config.cjs
jest.config.mjs 📜 feat: Improve Skill Authoring Guidance (#13517) 2026-06-04 18:36:16 -04:00
jest.setup.cjs 🌱 fix: Inject Code-Tool Files Into Graph Sessions on First Call (+ read_file Sandbox Fallback) (#12831) 2026-04-27 08:56:39 +09:00
package.json chore: Upgrade @google/genai SDK to ^2.8.0 (#13625) 2026-06-09 12:21:50 -04:00
tsconfig-paths-bootstrap.mjs
tsconfig.build.json
tsconfig.json 📦 chore: npm audit fixes and Mongoose 8.23 TypeScript follow-ups (#12996) 2026-05-07 09:47:40 -04:00
tsconfig.spec.json 📦 chore: Update TypeScript Config for TS v7 (#12794) 2026-04-23 12:51:03 -04:00
tsdown.config.mjs ️ refactor: Migrate @librechat/api build to tsdown (#13595) 2026-06-08 10:54:48 -04:00