feat: add native tools across provider clients - #9
Conversation
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>
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (5)
WalkthroughThe 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
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (17)
.beads/issues.jsonlAGENTS.mdREADME.mddocs/ARCHITECTURE.mddocs/NATIVE_TOOLS_RESEARCH.mddocs/REASONING_CAPABILITIES.mddocs/TRANSPILE_PLAN.mdexamples/native-gemini-tools.tsexamples/native-tool-serialization.tspackage.jsonsrc/llm/__tests__/anthropic-client.test.tssrc/llm/__tests__/factory.test.tssrc/llm/__tests__/gemini-client.test.tssrc/llm/__tests__/native-tools.test.tssrc/llm/__tests__/openai-client.test.tssrc/llm/anthropic.tssrc/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>
Summary
Agents can now use the same resolved
ToolDefinitionflow across all four provider clients instead of stopping at OpenAI. Anthropic Messages receives nativetool_use/tool_resultblocks, Gemini uses the current Interactions API, and OpenRouter/LiteLLM-compatible/custom routes retain the standard Chat Completions function dialect.Design decisions
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.Validation
Local release gate on
bdbe851dc12efe20bd4bc650ec594f6187f1000d:npm test— 40 files / 267 tests passednpm run typecheck— passednpm run lint— passednpm run build— passednpm run typecheck:examples— passednpm run test:examples— passednpm run typecheck:live— passednpm pack --dry-run—smolpaws-openhands-agent-0.3.3.tgz, package size 408.7 kB, unpacked size 2.0 MB, 75 filesgemini-3.5-flash-litedispatchedlookup_valuethenfinishand observed two signed thought blocksAnthropic 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.
This pull request was created by an AI agent (OpenHands) on behalf of Engel Nyst.
Summary by CodeRabbit
New Features
Documentation
Tests