fix(mcp): sanitize tool JSON Schemas so one bad tool can't break tool-calling (#2299)
* fix(mcp): sanitize tool JSON Schemas so one bad tool can't break tool-calling
MCP tool inputSchemas were forwarded to the provider verbatim. The HF MCP
server's `write_file` ships properties shaped `{ description, default: null }`
with no `type`, which strict OpenAI-compatible providers (Fireworks) reject
under tool_choice:"auto" - and rejecting one tool rejects the entire `tools`
array with HTTP 400. The MCP flow then falls back to a tool-less generation, so
the model answers as if it had no tools (e.g. "I don't have internet access")
even though the agentic/MCP badge was already shown.
Add a pure, non-mutating, schema-aware normalizer in `getOpenAiToolsForMcp`
that drops `default: null` and fills in a missing `type` (object/array when
implied by properties/items, else string), while only recursing into real
schema-bearing keywords so instance data (required, enum, defaults) and boolean
additionalProperties stay intact. Empty `{}` schemas are preserved as
match-anything so arbitrary maps (e.g. hf_jobs.args) are not narrowed to strings.
* fix(mcp): infer container type for patternProperties/additionalProperties maps
The type fallback only treated `properties`/`items` as structural hints, so a
map-shaped parameter defined via `patternProperties` (or only
`additionalProperties`/`propertyNames`) with no explicit `type` was coerced to
`type: "string"`, narrowing valid object arguments. Sub-schemas under
`patternProperties` were also not recursed, so a malformed one there could still
be rejected by strict providers.
Generalize the structural-keyword handling: recognize object applicators
(properties, patternProperties, additionalProperties, propertyNames, required)
and array applicators (items, prefixItems, contains) when inferring a missing
type, and recurse into patternProperties/propertyNames/prefixItems/contains.