How FreeLLMAPI Handles Cohere Tool Call Schema Differences
FreeLLMAPI automatically removes unsupported JSON Schema keys like additionalProperties and $schema from tool definitions before sending requests to Cohere's API, preventing 400 Bad Request errors while maintaining OpenAI-compatible tool-call functionality.
FreeLLMAPI provides a unified, OpenAI-compatible interface for multiple large language model providers. When working with Cohere's API, the Cohere tool call schema imposes stricter validation rules than other providers, rejecting certain standard JSON Schema keys that are harmless in OpenAI's implementation. To solve this, FreeLLMAPI implements a provider-specific sanitization layer that strips incompatible keys while preserving the rest of the tool definition.
The Problem: Cohere's Strict Schema Validation
Unlike OpenAI's permissive validation, Cohere's endpoint strictly enforces JSON Schema compliance for tool definitions. When FreeLLMAPI forwards a standard OpenAI-format tool definition containing certain schema metadata, Cohere responds with a 400 Bad Request error. Specifically, Cohere rejects the additionalProperties and $schema keys that many OpenAI-compatible clients include by default in their JSON Schema objects.
How FreeLLMAPI Strips Incompatible Keys
FreeLLMAPI solves the Cohere tool call schema compatibility issue through a three-stage sanitization pipeline defined in server/src/providers/cohere.ts and server/src/lib/tool-args.ts.
Identifying Unsupported Keys
The system first defines exactly which keys trigger Cohere's validation errors. In server/src/providers/cohere.ts at lines 21-22, the code declares a constant set of problematic keys:
const COHERE_UNSUPPORTED_SCHEMA_KEYS = new Set([
"additionalProperties",
"$schema"
]);
This explicit enumeration ensures that only the specific keys known to cause Cohere failures are targeted for removal.
The Sanitization Process
Before any API request, the sanitizeCohereTools helper processes the array of ChatToolDefinition objects. Located at lines 23-30 in server/src/providers/cohere.ts, this function walks through each tool and checks for function.parameters objects:
function sanitizeCohereTools(tools?: ChatToolDefinition[]) {
if (!tools || tools.length === 0) return tools;
return tools.map(t =>
t.function?.parameters
? {
...t,
function: {
...t.function,
parameters: stripSchemaKeys(
t.function.parameters,
COHERE_UNSUPPORTED_SCHEMA_KEYS
)
}
}
: t
);
}
This mapping preserves all other tool metadata—names, descriptions, and required parameters—while targeting only the schema object for cleaning.
Recursive Key Removal
The actual key removal happens in server/src/lib/tool-args.ts at lines 72-85 via the stripSchemaKeys utility. This generic function recursively traverses the JSON Schema object and deletes any property whose key appears in the supplied exclusion set:
function stripSchemaKeys(
obj: Record<string, any>,
keysToStrip: Set<string>
): Record<string, any> {
if (typeof obj !== "object" || obj === null) return obj;
const result: Record<string, any> = {};
for (const [key, value] of Object.entries(obj)) {
if (keysToStrip.has(key)) continue;
result[key] = stripSchemaKeys(value, keysToStrip);
}
return result;
}
This recursive approach handles nested schema definitions, ensuring that $schema or additionalProperties keys are removed regardless of their depth in the object hierarchy.
Implementation in the Cohere Provider
The sanitized tools are integrated into both standard and streaming completion flows. In server/src/providers/cohere.ts at lines 44-52, the CohereProvider.chatCompletion and CohereProvider.streamChatCompletion methods apply the sanitization before constructing the request payload:
// Inside CohereProvider class
async chatCompletion(apiKey: string, messages: Message[], model: string, options: ChatOptions) {
const sanitizedTools = sanitizeCohereTools(options.tools);
const requestBody = {
model,
messages,
tools: sanitizedTools, // Cohere-safe schema
stream: false
};
return fetch("https://api.cohere.ai/v1/chat", {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}` },
body: JSON.stringify(requestBody)
});
}
This ensures that whether you're calling command-r-plus for a single response or streaming tokens, the Cohere tool call schema receives only the keys it accepts.
Summary
- FreeLLMAPI maintains OpenAI compatibility by automatically sanitizing tool schemas for provider-specific restrictions.
- The
COHERE_UNSUPPORTED_SCHEMA_KEYSset explicitly targetsadditionalPropertiesand$schemaas the problematic keys rejected by Cohere. - The
sanitizeCohereToolsfunction inserver/src/providers/cohere.tsprocesses tool arrays before API transmission. - Recursive cleaning via
stripSchemaKeysinserver/src/lib/tool-args.tsensures nested schema objects are properly handled. - Sanitization applies to both
chatCompletionandstreamChatCompletionmethods, preventing 400 errors across all Cohere interaction modes.
Frequently Asked Questions
What specific JSON Schema keys does Cohere reject?
Cohere's API rejects the additionalProperties and $schema keys within tool parameter definitions. According to the FreeLLMAPI source code in server/src/providers/cohere.ts, these are defined in the COHERE_UNSUPPORTED_SCHEMA_KEYS constant and removed before every request to prevent validation failures.
How does FreeLLMAPI maintain OpenAI compatibility while supporting Cohere?
FreeLLMAPI accepts standard OpenAI-format tool definitions at its interface level, then applies provider-specific transformations internally. For Cohere, it strips incompatible schema keys via sanitizeCohereTools while leaving all other tool metadata—names, descriptions, and parameter types—completely unchanged, ensuring the same client code works across providers.
Can the schema stripping logic be reused for other providers?
Yes. The stripSchemaKeys function in server/src/lib/tool-args.ts is designed as a generic utility that accepts any set of keys to remove. FreeLLMAPI uses this same function for other providers like Google's Gemini that impose similar JSON Schema restrictions, making it a reusable component for handling strict validation requirements.
Where is the Cohere-specific sanitization logic located?
The Cohere-specific logic resides primarily in server/src/providers/cohere.ts, which contains the COHERE_UNSUPPORTED_SCHEMA_KEYS constant and the sanitizeCohereTools function. The underlying recursive removal utility is shared across providers and located in server/src/lib/tool-args.ts at lines 72-85.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →