Skip to content

[codex] fix llm tool schema shaping for near ai - #2951

Merged
henrypark133 merged 5 commits into
stagingfrom
fix/strict-schema
Apr 25, 2026
Merged

henrypark133 merged 5 commits into
stagingfrom
fix/strict-schema

Conversation

@henrypark133

Copy link
Copy Markdown
Collaborator

Summary

  • extract shared tool-schema shaping into src/llm/tool_schema.rs
  • keep strict OpenAI/Codex behavior on the rig adapter and Codex provider
  • switch NEAR AI chat completions to a provider-safe FlattenOnly policy so top-level combinators still flatten but optional fields stay optional

Why

NEAR AI was going through the same strict schema rewrite used by the strict OpenAI paths. That rewrote optional fields into required-nullable fields and pushed models toward sending null arguments that were not part of the original tool contract.

At the same time, NEAR AI still needs the top-level combinator flattening boundary for OpenAI-compatible tool requests, so the fix keeps that compatibility layer while removing the unwanted strictification.

Impact

  • NEAR AI tool requests preserve optional fields instead of converting them to required-nullable
  • NEAR AI still flattens top-level oneOf/anyOf/allOf/enum/not schemas before request serialization
  • strict OpenAI/Codex paths keep the previous strict behavior

Validation

  • cargo test test_convert_tool_definition_preserves_optional_fields --lib
  • cargo test test_convert_tool_definition_flattens_top_level_oneof_without_strictifying --lib
  • cargo test tool_schema::tests --lib
  • cargo test test_convert_tool_definition_handles_top_level_oneof_dispatcher --lib

@github-actions github-actions Bot added scope: llm LLM integration scope: docs Documentation size: XL 500+ changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Apr 24, 2026

@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 refactors tool schema normalization by introducing a dedicated tool_schema module that supports different policies: StrictOpenAi and FlattenOnly. This allows NearAiChatProvider to use a more permissive flattening strategy that preserves optional fields, while other providers continue to use strict normalization. The changes include moving existing logic from rig_adapter.rs to the new module and updating relevant providers and tests. Feedback suggests an optimization in tool_schema.rs to reduce redundant map lookups during recursive schema normalization.

Comment thread src/llm/tool_schema.rs
@henrypark133
henrypark133 marked this pull request as ready for review April 24, 2026 23:13
Copilot AI review requested due to automatic review settings April 24, 2026 23:13

Copilot AI 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.

Pull request overview

This PR centralizes provider-boundary JSON Schema shaping for tool definitions and adjusts NEAR AI’s tool schema behavior to avoid OpenAI strict-mode “required-nullable” rewriting while still flattening OpenAI-incompatible top-level combinators.

Changes:

  • Extracted shared tool schema shaping into src/llm/tool_schema.rs with a ToolSchemaPolicy (StrictOpenAi vs FlattenOnly).
  • Updated the rig adapter and Codex provider to keep strict OpenAI/Codex schema shaping.
  • Switched NEAR AI chat completions to FlattenOnly and updated/added tests + docs accordingly.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/llm/tool_schema.rs New shared schema shaping module with strict vs flatten-only policies + tests
src/llm/rig_adapter.rs Uses shared shaping for rig-based providers; removes in-file normalizer implementation
src/llm/openai_codex_provider.rs Uses shared shaping for Codex tool definitions
src/llm/nearai_chat.rs Uses FlattenOnly shaping and updates tests to verify optional-field preservation + flattening
src/llm/mod.rs Exposes the new tool_schema module within llm
src/llm/CLAUDE.md Updates documentation to reflect new shaping policies and provider behavior

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/llm/tool_schema.rs
Comment thread src/llm/openai_codex_provider.rs Outdated
Copilot AI review requested due to automatic review settings April 25, 2026 00:19

Copilot AI 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.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/llm/tool_schema.rs Outdated
Comment thread src/llm/tool_schema.rs Outdated
Comment thread src/llm/tool_schema.rs
@henrypark133
henrypark133 merged commit 7404e7d into staging Apr 25, 2026
18 checks passed
@henrypark133
henrypark133 deleted the fix/strict-schema branch April 25, 2026 02:39
ljanke-agents added a commit to ljanke/ironclaw that referenced this pull request Apr 27, 2026
Two sibling bugs in the OAuth direct-HTTP Anthropic provider that
blocked any tool-using request:

1. Tool input_schema not sanitized — t.parameters was passed raw, so
   any tool whose schema has top-level oneOf/anyOf/allOf returned
   "input_schema does not support oneOf, allOf, or anyOf at the top
   level". Sibling site missed by PR nearai#2951 (which fixed nearai_chat
   for the same Anthropic family of restrictions). Now routes through
   shape_tool_schema(FlattenOnly) to match nearai_chat.rs and the
   rig-based Anthropic path.

2. temperature parameter sent unconditionally — Anthropic deprecated
   it for the 4.7 family, returning "temperature is deprecated for
   this model.". Strip at the provider boundary by model-name pattern
   (-4-7) instead of patching every caller (heartbeat, compaction,
   dispatcher, routine engine all set temperature).

Tested locally with claude-haiku-4-5 (works). claude-opus-4-7 was
blocked by both issues; Claude.ai consumer OAuth tokens aren't
entitled to opus-4-7 anyway, which probably explains why upstream
didn't catch these (API-key-based testing has full model access).

Host: ironclaw-dev Model: claude-opus-4-7

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@henrypark133 henrypark133 mentioned this pull request Apr 29, 2026
This was referenced May 7, 2026
@ironclaw-ci ironclaw-ci Bot mentioned this pull request May 7, 2026
theredspoon pushed a commit to theredspoon/ironclaw that referenced this pull request Jun 21, 2026
* fix llm tool schema shaping for near ai

* fix clippy in tool schema shaping

* fix tool schema object-like handling

* fix explicit non-object schema flattening

* fix schema hint truncation handling
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules scope: docs Documentation scope: llm LLM integration size: XL 500+ changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants