Pure sanitizer for tool-parameter JSON schemas bound for the ElevenLabs Agents Platform.
ElevenLabs validates client-tool parameters schemas STRICTLY and its schema model only
allows enum on string-typed properties — a numeric enum such as
{ type: 'number', enum: [12, 14, 18, 24, 32] } is rejected at agents.create/update with
"Expected string. Received 12.". This provider quirk is handled here in the driver (never in
the tool definitions): the schema is deep-cloned and walked (nested objects, array items,
composition keywords — anything subschema-shaped); any NON-string node carrying enum has
the enum REMOVED and its allowed values appended to the node's description
("Allowed values: 12, 14, 18, 24, 32.") so the model still sees the constraint. String
enums and everything else pass through unchanged.
Pure and idempotent: the input is never mutated, and re-sanitizing a sanitized schema is a
no-op — which is what lets ElevenLabsRealtime.ToolSetFingerprint hash the sanitized
form on both the local and the round-tripped remote side without PATCH loops.
Pure sanitizer for tool-parameter JSON schemas bound for the ElevenLabs Agents Platform.
ElevenLabs validates client-tool
parametersschemas STRICTLY and its schema model only allowsenumon string-typed properties — a numeric enum such as{ type: 'number', enum: [12, 14, 18, 24, 32] }is rejected at agents.create/update with "Expected string. Received 12.". This provider quirk is handled here in the driver (never in the tool definitions): the schema is deep-cloned and walked (nested objects, arrayitems, composition keywords — anything subschema-shaped); any NON-string node carryingenumhas the enum REMOVED and its allowed values appended to the node'sdescription("Allowed values: 12, 14, 18, 24, 32.") so the model still sees the constraint. String enums and everything else pass through unchanged.Pure and idempotent: the input is never mutated, and re-sanitizing a sanitized schema is a no-op — which is what lets ElevenLabsRealtime.ToolSetFingerprint hash the sanitized form on both the local and the round-tripped remote side without PATCH loops.