Skip to content

fix(agents): apply Gemini schema cleaning for Gemini models via OpenAI-compat providers#91714

Closed
dwc1997 wants to merge 3 commits into
openclaw:mainfrom
dwc1997:fix/91542-gemini-anyof-cron-schema
Closed

fix(agents): apply Gemini schema cleaning for Gemini models via OpenAI-compat providers#91714
dwc1997 wants to merge 3 commits into
openclaw:mainfrom
dwc1997:fix/91542-gemini-anyof-cron-schema

Conversation

@dwc1997

@dwc1997 dwc1997 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Problem: isGeminiProvider only checked if the provider name contained "google" or "gemini". This missed OpenAI-compatible providers (like jjcc) that route to Gemini models, causing cron tool schema with anyOf to be rejected by Gemini's stricter validation.

Fix: Add model ID checking so Gemini schema cleaning is applied when the model ID contains "gemini", regardless of the provider name.

Linked context

Closes #91542

Real behavior proof

  • Behavior or issue addressed: Cron tool schema with anyOf rejected by Gemini via OpenAI-compat providers. The isGeminiProvider guard only checked the provider name for "google"/"gemini", so providers like "jjcc" that route to Gemini models were not recognized.
  • Real environment tested: Windows 10, Node.js v22.22.3, OpenClaw latest main, tsx loader
  • Exact steps or command run after this patch: node --import tsx/esm proof-91714.mjs (runs normalizeToolParameters with real OpenClaw code against a non-Google provider "jjcc" paired with model ID "gemini-2.0-flash")
  • Evidence after fix:
$ node --import tsx/esm proof-91714.mjs

======================================================================
PR #91714 -- Gemini schema cleaning for OpenAI-compat providers
======================================================================

Environment:
  Node.js:   v22.22.3
  Platform:  win32 x64

======================================================================
TEST 1: anyOf flattening for jjcc + gemini-2.0-flash
======================================================================

Input:  schema with anyOf (buy/sell branches) + required: [action, amount, ghost_field]
Provider: jjcc (non-Google), Model: gemini-2.0-flash

Output parameters:
  anyOf present:        false
  anyOf value:          undefined
  properties:           ["action","amount","price"]
  required:             ["action","amount"]
  ghost_field in req:   false

RESULT: PASS -- anyOf flattened, ghost_field stripped, properties merged

======================================================================
TEST 2: Unsupported keyword stripping for jjcc + gemini-2.0-flash
======================================================================

Input:  properties.name has minLength:1, maxLength:100
        properties.score has minimum:0, maximum:10
Provider: jjcc (non-Google), Model: gemini-2.0-flash

Output name schema:  {"type":"string"}
Output score schema: {"type":"number"}

RESULT: PASS -- minLength/maxLength/minimum/maximum stripped

======================================================================
TEST 3: Non-Gemini model ID preserves keywords (jjcc + gpt-4o)
======================================================================

Input:  properties.name has minLength:1, maxLength:100
Provider: jjcc (non-Google), Model: gpt-4o

Output name schema: {"type":"string","minLength":1,"maxLength":100}

RESULT: PASS -- minLength/maxLength preserved for non-Gemini model

======================================================================
SUMMARY: ALL TESTS PASSED
======================================================================
  • Observed result after fix: normalizeToolParameters now detects Gemini models by model ID when the provider name does not contain "google" or "gemini". Schema cleaning (anyOf flattening, unsupported keyword stripping, ghost required field removal) is applied for jjcc + gemini-2.0-flash, and correctly skipped for jjcc + gpt-4o. Three regression tests added in src/agents/agent-tools.schema.test.ts all pass (88/88 total).
  • What was not tested: Live end-to-end cron scheduling against a real Gemini endpoint via an OpenAI-compat proxy; only the schema normalization layer was verified.

Tests and validation

  • 88/88 tests pass (including 3 new regression tests in agent-tools.schema.test.ts)
  • Proof script runs normalizeToolParameters with real OpenClaw code against actual schema inputs

Risk checklist

  • userVisible: No (internal schema processing)
  • configEnvMigration: No
  • securityAuthNetwork: No
  • Mitigation: Only extends existing Gemini detection; non-Gemini models unaffected

Current review state

  • AI-assisted (built with Claude Code)

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 9, 2026
@clawsweeper

clawsweeper Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

This PR is a focused attempt at the linked Gemini-over-OpenAI-compatible schema bug, but it is superseded by a viable open PR that covers the same central fix and preserves the adjacent model-compat contracts this branch misses.

Root-cause cluster
Relationship: superseded
Canonical: #91559
Summary: The current PR and the canonical PR both target the same jjcc/Gemini cron schema bug; the canonical PR is open, mergeable, proof-positive, and covers the broader compatibility surface.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Canonical path: Close this branch as superseded and use #91559 as the canonical provider-normalizer fix path for the linked bug.

So I’m closing this here and keeping the remaining discussion on #91559.

Review details

Best possible solution:

Close this branch as superseded and use #91559 as the canonical provider-normalizer fix path for the linked bug.

Do we have a high-confidence way to reproduce the issue?

Yes at source level: current main passes modelId into tool normalization but only selects Gemini cleanup from provider id, while cron nullable union fields match the linked issue's rejected schema paths. I did not run a live jjcc/Gemini endpoint request in this read-only review.

Is this the best way to solve the issue?

No, this branch is no longer the best merge shape. The canonical PR fixes the same central normalizer path and also preserves toolSchemaProfile/cache behavior plus explicit unsupported-keyword stripping after Gemini cleanup.

Security review:

Security review cleared: The diff changes TypeScript schema-normalization logic and colocated tests only; it does not touch dependencies, lockfiles, workflows, credentials, downloads, or package execution surfaces.

AGENTS.md: found and applied where relevant.

What I checked:

  • Current main behavior: Current main normalizes tool schemas with provider, model id, and model compat available, but the Gemini cleanup predicate still only checks the provider id for google/gemini. (src/agents/agent-tools-parameter-schema.ts:771, 0a3e0d081dc4)
  • Caller context: The agent tool preparation path already passes modelProvider, modelId, and modelCompat into normalizeToolParameters, so the central normalizer is the right owner boundary for the fix. (src/agents/agent-tools.ts:1208, 0a3e0d081dc4)
  • Current PR diff: This PR adds model-id matching to the Gemini predicate, but does not add the related toolSchemaProfile detection/cache-key update or preserve custom unsupported-keyword stripping after Gemini cleanup. (src/agents/agent-tools-parameter-schema.ts:772, af889e847b69)
  • Superseding PR diff: The canonical open PR covers the same model-id cleanup and additionally includes toolSchemaProfile cache/detection and post-Gemini unsupported-keyword stripping. (src/agents/agent-tools-parameter-schema.ts:61, 8c05154bbe9e)
  • Superseding PR viability: The canonical PR is open, non-draft, mergeable, has proof supplied/sufficient labels, and closes the same linked bug issue. (8c05154bbe9e)
  • Linked issue context: The linked bug issue records both this PR and the canonical PR as closing references for the same jjcc/Gemini cron anyOf schema failure.

Likely related people:

  • steipete: GitHub commit history ties Peter Steinberger to provider compatibility docs, normalization-core extraction affecting this file, and Gemini required-field sanitizer work used by this path. (role: recent adjacent schema and model-compat contributor; confidence: high; commits: fffd72f36de9, fe1fd055d557, 00d8d7ead059; files: src/plugins/provider-model-compat.ts, src/config/types.models.ts, src/agents/schema/clean-for-gemini.ts)
  • vincentkoc: GitHub commit history shows recent work narrowing tool-schema helper exports, and the same author owns the broader overlapping provider-schema projection PR. (role: recent area contributor; confidence: medium; commits: e7e686db2d00; files: src/agents/agent-tools-parameter-schema.ts, src/agents/tool-schema-projection.ts, src/agents/tool-schema-json-projection.ts)
  • openperf: Commit 8c1ca1f removed OpenAPI-incompatible cron schema keywords for Gemini-backed validators, directly adjacent to the reported cron schema failure. (role: related cron schema compatibility contributor; confidence: medium; commits: 8c1ca1f24517; files: src/agents/tools/cron-tool.ts, src/agents/tools/cron-tool.schema.test.ts, src/agents/schema/clean-for-gemini.ts)

Codex review notes: model internal, reasoning high; reviewed against 0a3e0d081dc4.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. labels Jun 9, 2026
dwc1997 added a commit to dwc1997/openclaw that referenced this pull request Jun 15, 2026
…tion (openclaw#91714)

Add focused regression tests for non-Google providers with Gemini model IDs:
- Verifies unsupported keywords (minLength, maxLength, etc.) are stripped
- Verifies required fields are sanitized against merged properties
- Confirms non-Gemini model IDs do NOT trigger Gemini cleaning

Add proof-91714.mjs that runs normalizeToolParameters with a non-Google
provider (jjcc) and Gemini model ID, demonstrating the fix works end-to-end.

Co-Authored-By: Claude <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. and removed size: XS proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 15, 2026
@dwc1997

dwc1997 commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

Added regression tests and real behavior proof:

  • 3 regression tests in src/agents/agent-tools.schema.test.ts covering non-Google provider + Gemini model ID
  • 88/88 tests pass (including the new ones)
  • Proof script (proof-91714.mjs) runs normalizeToolParameters with real OpenClaw code, demonstrating the fix works end-to-end
  • All proof output captured in the PR body above

@clawsweeper

clawsweeper Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@openclaw-barnacle openclaw-barnacle Bot added size: S proof: supplied External PR includes structured after-fix real behavior proof. and removed size: M triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 15, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 15, 2026
dwc1997 added a commit to dwc1997/openclaw that referenced this pull request Jun 15, 2026
…tion (openclaw#91714)

Add focused regression tests for non-Google providers with Gemini model IDs:
- Verifies unsupported keywords (minLength, maxLength, etc.) are stripped
- Verifies required fields are sanitized against merged properties
- Confirms non-Gemini model IDs do NOT trigger Gemini cleaning

Add proof-91714.mjs that runs normalizeToolParameters with a non-Google
provider (jjcc) and Gemini model ID, demonstrating the fix works end-to-end.

Co-Authored-By: Claude <[email protected]>
@dwc1997
dwc1997 force-pushed the fix/91542-gemini-anyof-cron-schema branch from b3b9bd7 to 848e90c Compare June 15, 2026 18:59
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 15, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 15, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 15, 2026
dwc1997 added a commit to dwc1997/openclaw that referenced this pull request Jun 16, 2026
…tion (openclaw#91714)

Add focused regression tests for non-Google providers with Gemini model IDs:
- Verifies unsupported keywords (minLength, maxLength, etc.) are stripped
- Verifies required fields are sanitized against merged properties
- Confirms non-Gemini model IDs do NOT trigger Gemini cleaning

Add proof-91714.mjs that runs normalizeToolParameters with a non-Google
provider (jjcc) and Gemini model ID, demonstrating the fix works end-to-end.

Co-Authored-By: Claude <[email protected]>
@dwc1997
dwc1997 force-pushed the fix/91542-gemini-anyof-cron-schema branch from 848e90c to 22d4fc3 Compare June 16, 2026 00:25
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 16, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 16, 2026
dwc1997 and others added 3 commits June 16, 2026 21:58
…I-compat providers

Previously, isGeminiProvider only checked if the provider name contained
"google" or "gemini". This missed OpenAI-compatible providers (like jjcc)
that route to Gemini models, causing cron tool schema with anyOf to be
rejected by Gemini's stricter validation.

This fix adds model ID checking so Gemini schema cleaning is applied
when the model ID contains "gemini", regardless of the provider name.

Closes openclaw#91542

Co-Authored-By: Claude Opus 4.8 <[email protected]>
…tion (openclaw#91714)

Add focused regression tests for non-Google providers with Gemini model IDs:
- Verifies unsupported keywords (minLength, maxLength, etc.) are stripped
- Verifies required fields are sanitized against merged properties
- Confirms non-Gemini model IDs do NOT trigger Gemini cleaning

Add proof-91714.mjs that runs normalizeToolParameters with a non-Google
provider (jjcc) and Gemini model ID, demonstrating the fix works end-to-end.

Co-Authored-By: Claude <[email protected]>
The proof-91714.mjs file at the repo root is flagged by
check-duplicates.mjs as a tracked file outside scan targets.
The proof output is now fully embedded in the PR body.
@dwc1997
dwc1997 force-pushed the fix/91542-gemini-anyof-cron-schema branch from 22d4fc3 to af889e8 Compare June 16, 2026 13:59
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 16, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 🛠️ actively grinding The PR author has acted after the latest ClawSweeper review and work remains. labels Jun 19, 2026
@clawsweeper

clawsweeper Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Gemini (jjcc/openai-compat) rejects cron tool schema: anyOf properties missing type field in v2026.6.1

1 participant