Skip to content

fix(tools): keep opaque object schemas open - #3097

Merged
diegosouzapw merged 3 commits into
diegosouzapw:release/v3.8.9from
nmime:fix/gpt55-opaque-tool-schemas
Jun 3, 2026
Merged

diegosouzapw merged 3 commits into
diegosouzapw:release/v3.8.9from
nmime:fix/gpt55-opaque-tool-schemas

Conversation

@nmime

@nmime nmime commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Branch now: https://github.com/nmime/OmniRoute/tree/fix/gpt55-opaque-tool-schemas

Current branch head: e9ac478

Compare against diegosouzapw/OmniRoute:main:

ahead: 1
behind: 0
What was fixed:

Original branch was accidentally based on stale nmime/main, causing 104 ahead / 931 behind.
I rebuilt the fix branch from current diegosouzapw/OmniRoute:main.
Reapplied only the OmniRoute tool-schema fix.
Removed the dumb long comment from:
open-sse/services/toolSchemaSanitizer.ts
open-sse/translator/helpers/schemaCoercion.ts
Verified comment matches now: 0.
What the code fix does:

Before: empty object tool schemas like { type: "object", properties: {} } could make GPT-5.5/Codex prune nested values to {}.
Example broken case: SPLOX_EXECUTE_TOOL.args became {} instead of { action: "create" }.
Now: unspecified empty object schemas are kept open with additionalProperties: true.
Explicitly closed schemas still stay closed with additionalProperties: false.
Tests/checks:

Focused unit tests: 26 passed
Branch clean: 1 commit ahead, 0 behind
Production still working:
PM2 process alive: yes
local /status: 200
public /status: 200
runtime check: args.additionalProperties=true

@nmime
nmime requested a review from diegosouzapw as a code owner June 3, 2026 10:35

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces changes to keep opaque object schemas open-world by setting additionalProperties: true when properties is undefined or empty. This logic is implemented in both toolSchemaSanitizer.ts and schemaCoercion.ts, and is accompanied by a new unit test suite. The review feedback suggests enhancing the object schema detection in both files to correctly handle cases where the schema type is defined as an array of strings (e.g., ["object", "null"]) to support nullable objects.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +33 to +35
const properties = schema.properties;
const isObjectSchema = schema.type === "object" || isPlainObject(properties);
if (!isObjectSchema) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In JSON Schema, the type property can sometimes be defined as an array of strings (for example, type: ["object", "null"] to represent a nullable object). To ensure these schemas are also correctly identified as object schemas when properties is undefined, we should check if type is either "object" or an array containing "object".

  const properties = schema.properties;
  const type = schema.type;
  const isObjectSchema =
    type === "object" ||
    (Array.isArray(type) && type.includes("object")) ||
    isPlainObject(properties);
  if (!isObjectSchema) return;

Comment on lines +38 to +40
const properties = schema.properties;
const isObjectSchema = schema.type === "object" || isPlainObject(properties);
if (!isObjectSchema) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In JSON Schema, the type property can sometimes be defined as an array of strings (for example, type: ["object", "null"] to represent a nullable object). To ensure these schemas are also correctly identified as object schemas when properties is undefined, we should check if type is either "object" or an array containing "object".

  const properties = schema.properties;
  const type = schema.type;
  const isObjectSchema =
    type === "object" ||
    (Array.isArray(type) && type.includes("object")) ||
    isPlainObject(properties);
  if (!isObjectSchema) return;

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e9ac4786eb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (isPlainObject(parameters)) return sanitizeSchema(parameters);
if (parameters === null || parameters === undefined) {
return { type: "object", properties: {} };
return { type: "object", properties: {}, additionalProperties: true };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update sanitizer expectations for open schemas

When parameters is null or omitted, this now returns { type: "object", properties: {}, additionalProperties: true }, but the existing tests/unit/tool-schema-sanitizer.test.mjs cases for missing/null Chat Completions parameters and missing Responses parameters still assert the old { type: "object", properties: {} } shape. That leaves the committed unit suite failing for this intentional behavior change, so the old expectations need to be updated alongside this return value.

Useful? React with 👍 / 👎.

@kilo-code-bot

kilo-code-bot Bot commented Jun 3, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (3 files)
  • open-sse/services/toolSchemaSanitizer.ts
  • open-sse/translator/helpers/schemaCoercion.ts
  • tests/unit/openai-tool-opaque-object-schema.test.ts

Reviewed by laguna-m.1-20260312:free · 3,348,714 tokens

@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.8.9 June 3, 2026 21:00
…es:true

The opaque-schema fix intentionally injects additionalProperties:true on empty
object schemas (incl. the web_search passthrough shim and null/missing parameter
fallbacks). Update the pre-fix snapshot assertions to match the new behavior.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d458501793

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

result.else = coerceSchemaNumericFields(result.else);
}

keepOpaqueObjectSchemasOpen(result);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid re-adding unsupported Gemini schema keyword

For Gemini/Antigravity targets, openaiToGeminiBase() has already converted tools via buildGeminiTools(), whose cleanJSONSchemaForAntigravity() strips additionalProperties because Gemini function declarations reject it with Unknown name. This new final pass runs afterward on functionDeclarations.parameters, so an empty object parameter schema gets additionalProperties: true reintroduced and those Gemini tool requests can start failing with 400s.

Useful? React with 👍 / 👎.

@diegosouzapw

Copy link
Copy Markdown
Owner

Thanks, @nmime! 🙏 Keeping opaque object schemas open (injecting additionalProperties: true on empty object schemas) is the right fix for GPT-5.5/Codex pruning untyped nested payloads. I pushed a small follow-up aligning the pre-fix snapshot assertions in translator-claude-to-openai and tool-schema-sanitizer to the new intended output. Merged into release/v3.8.9 for the next release.

@diegosouzapw
diegosouzapw merged commit 27b822e into diegosouzapw:release/v3.8.9 Jun 3, 2026
2 checks passed
@diegosouzapw diegosouzapw mentioned this pull request Jun 3, 2026
diegosouzapw added a commit that referenced this pull request Jun 3, 2026
…ors hall

Adds entries for #3097, #3101 (deepseek-web #2942/#2820), #3104, #3105, #3107,
#3109, #3111, #3113, #3115, #3122, #3125, #3127, #3129, plus a Contributors
section crediting all v3.8.9 contributors. Stamps the 3.8.9 release date.
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
* fix(tools): keep opaque object schemas open

* test: align opaque-object-schema expectations with additionalProperties:true

The opaque-schema fix intentionally injects additionalProperties:true on empty
object schemas (incl. the web_search passthrough shim and null/missing parameter
fallbacks). Update the pre-fix snapshot assertions to match the new behavior.

---------

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
* fix(tools): keep opaque object schemas open

* test: align opaque-object-schema expectations with additionalProperties:true

The opaque-schema fix intentionally injects additionalProperties:true on empty
object schemas (incl. the web_search passthrough shim and null/missing parameter
fallbacks). Update the pre-fix snapshot assertions to match the new behavior.

---------

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
* fix(tools): keep opaque object schemas open

* test: align opaque-object-schema expectations with additionalProperties:true

The opaque-schema fix intentionally injects additionalProperties:true on empty
object schemas (incl. the web_search passthrough shim and null/missing parameter
fallbacks). Update the pre-fix snapshot assertions to match the new behavior.

---------

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants