You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using non-strict OpenAI-compatible providers like Dahl (inference.dahl.global), LMSpeed, or other proxies that validate JSON Schema strictly, pi crashes with:
Error: 400 {"message":"tools[N].function.parameters: schema reference keyword is forbidden: \"$ref\" is not allowed"}
This affects any extension or MCP tool whose parameter schema uses $ref, $dynamicRef, $recursiveRef, $defs, or definitions keywords — which is common for tools built with TypeBox, Zod, or JSON Schema reference patterns.
Root Cause
Commit 7915cda ("feat(ai): add strict tool schema conversion") introduced UNSUPPORTED_STRICT_SCHEMA_KEYS and validates them only for strict-mode providers (OpenAI, Anthropic native). For non-strict providers, getJsonSchemaToolParameters returns the raw tool.parameters unchanged, passing $ref-containing schemas directly to the provider API.
The upstream code already recognizes these keys as problematic:
But this validation is gated behind strict === true, so it never runs for the vast majority of OpenAI-compatible proxy providers.
Affected Tools (observed)
memory_search from pi-hermes-memory v0.9.4 — triggers $ref 400 on tools[20/21]
terminal_commander_shell_exec / terminal_commander_shell_session_exec — triggers $ref 400, and after stripping $ref, the schema still exceeds Dahl's 256-node complexity limit
Any MCP tool whose schema contains $ref pointers
Reproduction
# Set up a Dahl provider in models.json# Select moonshotai/Kimi-K2.6 and send any prompt# Result: Error: 400 {"message":"tools[21].function.parameters: schema reference keyword is forbidden: \"$ref\" is not allowed"}
Proposed Fix
A lightweight sanitization step applied in the non-strict path of openai-completions.ts and openai-responses-shared.ts, before calling getJsonSchemaToolParameters. The function would:
Strip unsupported keywords recursively from all schemas — removing $ref, $dynamicRef, $recursiveRef, $defs, definitions and any other keys from UNSUPPORTED_STRICT_SCHEMA_KEYS
Cap schema complexity — for schemas exceeding a reasonable node count (e.g., 200), collapse to only top-level type, flattened properties (type only), and required
Be placed alongside the existing strict conversion logic in constrained-sampling.ts so the key list is shared
Example approach:
// In constrained-sampling.ts, near makeStrictJsonSchemaexportfunctionsanitizeToolParameters(schema: unknown): unknown{// Strip $ref/$defs/definitions recursively, collapse complex schemas// Returns self-contained schema safe for any OpenAI-compatible provider}
// In openai-completions.ts convertTools()
parameters: sanitizeToolParameters(getJsonSchemaToolParameters(tool,strict))
Why This Matters
Dahl and similar providers are popular OpenAI-compatible proxies with no strict-schema workarounds
Extension tool schemas (TypeBox, Zod, MCP adapters) routinely use $ref — this is standard JSON Schema practice
The upstream team has already identified these keys as "unsupported" — the fix is about extending that guard to the non-strict path
Without this, users of any strict-validating proxy are blocked from using extensions that reference schemas
Workaround (current)
Users apply a post-install patch script (fix-pi-ai.mjs) that modifies dist/api/openai-completions.js and dist/api/openai-responses-shared.js to wrap parameter schemas through a custom stripDefs/simplifySchema function. This works but breaks on every pi update and requires manual re-application.
Happy to submit a PR with the fix if the approach is acceptable.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Problem
When using non-strict OpenAI-compatible providers like Dahl (
inference.dahl.global), LMSpeed, or other proxies that validate JSON Schema strictly, pi crashes with:This affects any extension or MCP tool whose parameter schema uses
$ref,$dynamicRef,$recursiveRef,$defs, ordefinitionskeywords — which is common for tools built with TypeBox, Zod, or JSON Schema reference patterns.Root Cause
Commit
7915cda("feat(ai): add strict tool schema conversion") introducedUNSUPPORTED_STRICT_SCHEMA_KEYSand validates them only for strict-mode providers (OpenAI, Anthropic native). For non-strict providers,getJsonSchemaToolParametersreturns the rawtool.parametersunchanged, passing$ref-containing schemas directly to the provider API.The upstream code already recognizes these keys as problematic:
But this validation is gated behind
strict === true, so it never runs for the vast majority of OpenAI-compatible proxy providers.Affected Tools (observed)
memory_searchfrompi-hermes-memoryv0.9.4 — triggers$ref400 on tools[20/21]terminal_commander_shell_exec/terminal_commander_shell_session_exec— triggers$ref400, and after stripping$ref, the schema still exceeds Dahl's 256-node complexity limit$refpointersReproduction
Proposed Fix
A lightweight sanitization step applied in the non-strict path of
openai-completions.tsandopenai-responses-shared.ts, before callinggetJsonSchemaToolParameters. The function would:$ref,$dynamicRef,$recursiveRef,$defs,definitionsand any other keys fromUNSUPPORTED_STRICT_SCHEMA_KEYStype, flattenedproperties(type only), andrequiredconstrained-sampling.tsso the key list is sharedExample approach:
Why This Matters
$ref— this is standard JSON Schema practiceWorkaround (current)
Users apply a post-install patch script (
fix-pi-ai.mjs) that modifiesdist/api/openai-completions.jsanddist/api/openai-responses-shared.jsto wrap parameter schemas through a customstripDefs/simplifySchemafunction. This works but breaks on everypi updateand requires manual re-application.Happy to submit a PR with the fix if the approach is acceptable.
All reactions