0xPlaygrounds / 0xPlaygrounds/rig

bug(Responses API) `strict: false` is never sent, so OpenAI silently enables strict mode

Offen
#2,477 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug
Vorherrschende Sprache
Rust
Sterne
8.6k
Forks
959
Ø Merge
4 Std. 32 Min.
Gemergte PRs (30 T.)
117

Beschreibung

- [x] I have looked for existing issues (including closed) about this

## Bug Report
[`ResponsesToolDefinition::strict` has `skip_serializing_if = "is_false"`](https://github.com/0xPlaygrounds/rig/blob/18c95c9d9541decc02d008a72314a15ac5ecddb8/crates/rig-core/src/providers/openai/responses_api/mod.rs#L734-L739). A non-strict function tool therefore reaches the wire with no strict key at all.

For the Responses API, an omitted strict does not mean non-strict. [The OpenAI function-calling guide says](https://developers.openai.com/api/docs/guides/function-calling?api-mode=responses#strict-mode):

> If you omit strict, the default depends on the API: Responses requests will attempt to normalize your schema into strict mode when possible, and will fall back to non-strict, best-effort function calling if the schema cannot be made compatible with strict mode.

> To opt out of strict mode in Responses and keep non-strict, best-effort function calling, explicitly set strict: false.

So the "non-strict by default" behavior that #1991 intended is not what the server does. Any strict-compatible schema is normalized into strict mode, and every property becomes required.

## Reproduction
I ran a tool with two optional object properties (not in required, no null type) against gpt-5.6 through `ResponsesCompletionModel::stream`, with `strict_tools` left at its default `false`. In more than 1000 tool calls the model never omitted an optional property once. For the optional object properties it emitted `{"fact": "", ...}` with empty strings, because constrained decoding forced the key to be present and the schema offered no null. The model's own text said it would omit the field, and the next call still carried it.

## Expected behavior

A tool built with `ResponsesToolDefinition::function(..)` or converted from `completion::ToolDefinition` should reach the wire as `"strict": false`, so the server keeps best-effort function calling as the rig docs promise.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.