Skip to content

feat: add native tools across provider clients - #9

Merged
smolpaws merged 7 commits into
mainfrom
feature/native-tool-calling
Aug 1, 2026
Merged

feat: add native tools across provider clients#9
smolpaws merged 7 commits into
mainfrom
feature/native-tool-calling

Conversation

@smolpaws

@smolpaws smolpaws commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

Agents can now use the same resolved ToolDefinition flow across all four provider clients instead of stopping at OpenAI. Anthropic Messages receives native tool_use/tool_result blocks, Gemini uses the current Interactions API, and OpenRouter/LiteLLM-compatible/custom routes retain the standard Chat Completions function dialect.

Design decisions

  • Anthropic continuation keeps parallel tool results in one user turn, replays every signed thinking block, and rejects malformed arguments or missing call IDs before emitting invalid provider payloads.
  • Gemini runs Interactions with store: false, making the durable SDK transcript sufficient for restore and forks. Signed thoughts, parallel function calls, and function results round-trip as typed steps.
  • OpenAI-compatible routes reuse the existing Chat Completions serializer only when the endpoint implements that dialect; the SDK does not guess or translate nonstandard proxy formats.
  • Unknown future provider response blocks remain forward-compatible, while malformed blocks of known types fail closed.

Validation

Local release gate on bdbe851dc12efe20bd4bc650ec594f6187f1000d:

  • npm test — 40 files / 267 tests passed
  • npm run typecheck — passed
  • npm run lint — passed
  • npm run build — passed
  • npm run typecheck:examples — passed
  • credential-free npm run test:examples — passed
  • npm run typecheck:live — passed
  • npm pack --dry-runsmolpaws-openhands-agent-0.3.3.tgz, package size 408.7 kB, unpacked size 2.0 MB, 75 files
  • live Gemini Interactions smoke with gemini-3.5-flash-lite dispatched lookup_value then finish and observed two signed thought blocks

Anthropic was intentionally not called live because the available credential has no billing credit. Its request and continuation behavior is covered by focused wire-shape tests and the bounded prior implementation reference.


Compound Engineering

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

Summary by CodeRabbit

  • New Features

    • Added native tool-calling support across Anthropic, Gemini, OpenAI, and OpenAI-compatible providers.
    • Added parallel tool calls, tool-result continuation, reasoning/thought replay, and provider-specific formatting.
    • Migrated Gemini integration to the Interactions API.
    • Added live Gemini tool-calling and cross-provider serialization examples.
  • Documentation

    • Expanded provider compatibility, configuration, architecture, and tool-calling guidance.
  • Tests

    • Added comprehensive coverage for serialization, parsing, validation, continuation flows, and provider-specific behavior.

enyst and others added 6 commits July 31, 2026 17:03
Complete research bead openhands-agent-tools-research. Created comprehensive
research document at docs/NATIVE_TOOLS_RESEARCH.md covering:

- Anthropic Messages API: tools array with name/description/input_schema,
  tool_use content blocks, tool_result continuation in user messages
- Gemini Interactions API: type:function tools, function_call steps,
  function_result inputs, previous_interaction_id for stateful mode
  (NOTE: use Interactions API, not legacy generateContent)
- OpenAI-compatible: reuse Chat Completions shape, provider gating strategy

Captured proven data shapes from oh-tab reference implementation and official
docs. Documented 4-phase implementation plan: Anthropic → Gemini Interactions
migration + tools → OpenAI-compatible gating → cross-provider validation.

All official docs referenced with exact request/response formats, tool-call IDs,
continuation shapes, and edge cases noted.

Co-authored-by: smolpaws <engel@enyst.org>
Complete bead openhands-agent-tools-anthropic. Implemented native tool calling
for AnthropicMessagesClient:

- Added tools parameter to AnthropicMessagesClient.complete()
- Added toAnthropicTool() to serialize ToolDefinition to Anthropic format:
  {name, description, input_schema}
- buildAnthropicMessagesBody() now adds tools array and tool_choice: auto
- Added anthropicToolUseBlockSchema to response parsing
- parseAnthropicMessagesResponse() extracts tool_use blocks → MessageToolCall[]
- fromAnthropicToolUse() converts tool_use to MessageToolCall with JSON
  serialized arguments
- Tool result continuation already worked via existing toAnthropicMessage()

Tests (11 total, all pass):
- Request serialization with tools (native format)
- No-tools omission (don't send empty tools array)
- tool_use block parsing into MessageToolCall
- Parallel tool calls handling
- Tool result continuation serialization
- Invalid tool arguments gracefully handled (fallback to string)

All 250 tests pass. No live Anthropic API calls per instructions.

Co-authored-by: smolpaws <engel@enyst.org>
Move GeminiClient to the current stateless Interactions API so the durable SDK transcript remains the conversation source of truth. Serialize ToolDefinition schemas as flat function tools, replay signed thoughts and function steps, parse parallel calls, and return function results in native form.

Add focused request/response tests and a credential-gated live example. A real gemini-3.5-flash-lite run dispatched lookup_value and finish successfully; all 254 tests plus typecheck, lint, build, and example typecheck pass.

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

Co-authored-by: openhands <openhands@all-hands.dev>
Prove that the existing OpenAI Chat Completions tool path works unchanged for OpenRouter, LiteLLM-compatible base URLs, and custom gateways, including assistant tool-call parsing and tool-result replay.

Document the compatibility boundary: gateways must expose the standard Chat Completions function-tool dialect; the SDK does not guess nonstandard payloads or translate proxy traffic into native Anthropic/Gemini shapes.

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

Co-authored-by: openhands <openhands@all-hands.dev>
Add a shared ToolDefinition serialization matrix and keyless example across Chat Completions, Responses, Anthropic Messages, and Gemini Interactions. Tighten Gemini malformed-step and missing-call-id handling so invalid replay fails locally.

Align architecture, research, reasoning, transpile, README, and repository notes with the completed provider flow and live-test policy. All 261 tests and release-quality checks pass; the credential-gated Gemini smoke succeeded with gemini-3.5-flash-lite and Anthropic was not called live.

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

Co-authored-by: openhands <openhands@all-hands.dev>
Group parallel Anthropic results into one user turn, preserve every signed thinking block, and reject malformed replay metadata before sending invalid provider payloads. Expand Gemini stateless replay coverage and make its live smoke prove signed-thought continuity.

Record the independent audit evidence in Beads and align the provider research notes with the implemented fail-fast and stateless behavior.

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 Aug 1, 2026
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b83c1945-eaa5-4426-a7a3-6a9be40e2d6d

📥 Commits

Reviewing files that changed from the base of the PR and between bdbe851 and 8b83258.

📒 Files selected for processing (6)
  • .beads/issues.jsonl
  • docs/REASONING_CAPABILITIES.md
  • src/llm/__tests__/anthropic-client.test.ts
  • src/llm/__tests__/gemini-client.test.ts
  • src/llm/anthropic.ts
  • src/llm/gemini.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • .beads/issues.jsonl
  • docs/REASONING_CAPABILITIES.md
  • src/llm/anthropic.ts
  • src/llm/tests/anthropic-client.test.ts
  • src/llm/gemini.ts

Walkthrough

The change adds native tool support for Anthropic Messages, Gemini Interactions, and OpenAI-compatible routes. Anthropic now serializes tools, parses tool-use blocks, groups results, and replays signed thinking. Gemini now uses stateless Interactions requests with function tools, thought replay, and function-call parsing. Tests cover provider-specific behavior and shared serialization. Documentation and examples describe the provider flows.

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant LLMClient
  participant ProviderAPI
  participant Tool
  Agent->>LLMClient: Send messages and tool definitions
  LLMClient->>ProviderAPI: Serialize provider-native request
  ProviderAPI-->>LLMClient: Return text or tool call
  LLMClient-->>Agent: Return completion and tool calls
  Agent->>Tool: Execute requested function
  Tool-->>Agent: Return tool result
  Agent->>LLMClient: Send tool result continuation
  LLMClient->>ProviderAPI: Serialize continuation request
Loading

Possibly related PRs

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding native tool support across the provider clients.
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.

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 6


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 67dda758-a7f9-47af-81b0-b001446a19d5

📥 Commits

Reviewing files that changed from the base of the PR and between 1c9fde0 and bdbe851.

📒 Files selected for processing (17)
  • .beads/issues.jsonl
  • AGENTS.md
  • README.md
  • docs/ARCHITECTURE.md
  • docs/NATIVE_TOOLS_RESEARCH.md
  • docs/REASONING_CAPABILITIES.md
  • docs/TRANSPILE_PLAN.md
  • examples/native-gemini-tools.ts
  • examples/native-tool-serialization.ts
  • package.json
  • src/llm/__tests__/anthropic-client.test.ts
  • src/llm/__tests__/factory.test.ts
  • src/llm/__tests__/gemini-client.test.ts
  • src/llm/__tests__/native-tools.test.ts
  • src/llm/__tests__/openai-client.test.ts
  • src/llm/anthropic.ts
  • src/llm/gemini.ts

Comment thread .beads/issues.jsonl Outdated
Comment thread docs/REASONING_CAPABILITIES.md Outdated
Comment thread src/llm/anthropic.ts Outdated
Comment thread src/llm/anthropic.ts
Comment thread src/llm/gemini.ts
Comment thread src/llm/gemini.ts
Round-trip Anthropic redacted thinking blocks alongside signed thinking, and make Gemini reject malformed known text content without swallowing it through the forward-compatible fallback.

Correct the malformed-content regression input and reconcile review findings in docs and Beads.

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

Co-authored-by: openhands <openhands@all-hands.dev>
@smolpaws
smolpaws merged commit 30e160f into main Aug 1, 2026
2 checks passed
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