Skip to content

Pass native tools to OpenAI completions - #7

Merged
smolpaws merged 2 commits into
mainfrom
fix/native-tool-propagation
Jul 14, 2026
Merged

Pass native tools to OpenAI completions#7
smolpaws merged 2 commits into
mainfrom
fix/native-tool-propagation

Conversation

@smolpaws

@smolpaws smolpaws commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • extend LLMClient.complete with an optional typed ToolDefinition[] and pass exactly the usable Agent tools
  • serialize provider-native function tools for OpenAI Chat Completions and Responses while omitting tools for empty requests
  • add red/green unit coverage plus a live gpt-5-nano read/edit/finish example

Upstream parity

The Python Agent passes its resolved tool definitions to LLM completion. This restores that boundary in the TypeScript SDK without adding provider work outside OpenAI. Existing Anthropic, Gemini, testing, and custom clients remain source-compatible because the new argument is optional.

Pinned Python symbol / behavior TypeScript symbol / behavior Test evidence Intentional differences
Agent.step() / astep() pass list(self.tools_map.values()) to make_llm_completion() / amake_llm_completion() Agent.step() passes this.tools.filter(tool => tool.usable) to LLMClient.complete() src/agent/__tests__/tool-propagation.test.ts TS receives already-resolved ToolDefinitions and excludes definitions marked unusable; no server-only shim
make_llm_completion(..., tools) routes the same definitions to completion or Responses LLMClient.complete(messages, tools?) is the thin shared boundary Agent propagation test; all provider/custom clients type-check Optional parameter preserves existing TS client compatibility; empty OpenAI wire requests omit tools
LLM._finalize_completion_params() / _finalize_responses_params() call ToolDefinition.to_openai_tool() / to_responses_tool() OpenAI request builders derive schemas from ToolDefinition.toResponsesTool() and wrap only the Chat function shape src/llm/__tests__/openai-client.test.ts Idiomatic helper reuse; Chat sends explicit strict: false; Anthropic/Gemini expansion remains out of scope
Multiple returned calls become ordered actions and parallel observations dispatchLlmResponse() preserves every call; ParallelToolExecutor executes batches in input order response-dispatch.test.ts; parallel-executor.test.ts; live read/edit/finish smoke Security/confirmation gates remain an accepted deviation; pending/multi-tool execution is retained

Validation

  • npm test — 244/244 passed
  • npm run typecheck
  • npm run lint
  • npm run build
  • npm run typecheck:examples
  • credential-free npm run test:examples
  • npm run typecheck:live
  • npm pack --dry-run
  • npm run live:openai-toolsgpt-5-nano emitted native actions read_file, edit_file, read_file, finish; executors ran and the file mutation was verified

Live workflow

Label this PR test-examples to run the example suite with OPENAI_API_KEY from the existing examples GitHub Environment. No credential values are printed.

This pull request was created by an AI agent (OpenHands) on behalf of Engel Nyst.

Summary by CodeRabbit

  • New Features
    • Agents now propagate only usable tools to the language model and execute returned tool calls.
    • OpenAI chat/completions and responses integrations now support native tool definitions.
    • Added a runnable native tools example (read/edit/finish) and a live:openai-tools command to run it.
  • Bug Fixes
    • Tool definitions are omitted from requests when no tools are available.
    • Non-usable tools are no longer exposed to the language model.
  • Documentation / Tests
    • Updated architecture and parity docs; added coverage validating tool propagation and OpenAI serialization.

Propagate usable Agent tools through the typed LLM client boundary and serialize provider-native function tools for both OpenAI APIs. Add red/green coverage and a live gpt-5-nano read/edit/finish smoke.

Co-authored-by: smolpaws <engel@enyst.org>

Co-authored-by: openhands <openhands@all-hands.dev>
@smolpaws smolpaws added the test-examples Tracks CI/example-test coverage. Created by OpenHands for Engel. label Jul 14, 2026
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The completion contract now accepts optional tool definitions. OpenAI chat and responses clients serialize those tools using provider-specific request shapes and omit the field when no tools are provided. Agent.step() forwards only usable tools and processes returned tool calls. A new executable example demonstrates native read, edit, and finish dispatch, with assertions, cleanup, and an npm script.

Sequence Diagram(s)

sequenceDiagram
  participant LocalConversation
  participant Agent
  participant OpenAIClient
  participant NativeTools
  LocalConversation->>Agent: run conversation with tool definitions
  Agent->>OpenAIClient: complete messages and usable tools
  OpenAIClient-->>Agent: native tool call
  Agent->>NativeTools: execute read_file or edit_file
  NativeTools-->>Agent: tool observation
  Agent->>OpenAIClient: complete updated conversation
  OpenAIClient-->>Agent: native finish call
  Agent-->>LocalConversation: finished conversation state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: passing native tools through OpenAI completions.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces native tool support for OpenAI clients (both Chat Completions and Responses APIs). It updates the LLMClient.complete interface to accept an optional list of ToolDefinitions, modifies Agent.step() to pass only usable tools, and handles native tool serialization for OpenAI payloads while omitting the tools field when empty. The changes also include a new live example, updated documentation, and comprehensive unit tests for tool propagation and serialization. I have no feedback to provide as there are no review comments and the implementation is clean and well-tested.

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.

@enyst enyst left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@/tmp/pr7_review_body.md

Record the pinned Python Agent-to-LLM ToolDefinition contract, provider serialization ownership, preserved multi-tool dispatch, and the closed transpilation gap.

Co-authored-by: smolpaws <engel@enyst.org>

Co-authored-by: openhands <openhands@all-hands.dev>
@smolpaws
smolpaws merged commit 7bb73bb into main Jul 14, 2026
2 checks passed
@smolpaws smolpaws mentioned this pull request Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test-examples Tracks CI/example-test coverage. Created by OpenHands for Engel.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants