Skip to content

fix(rig-gemini-grpc): populate FunctionDeclaration.parameters from ToolDefinition#1763

Open
abhicris wants to merge 1 commit into
0xPlaygrounds:mainfrom
abhicris:fix/gemini-grpc-tool-parameters
Open

fix(rig-gemini-grpc): populate FunctionDeclaration.parameters from ToolDefinition#1763
abhicris wants to merge 1 commit into
0xPlaygrounds:mainfrom
abhicris:fix/gemini-grpc-tool-parameters

Conversation

@abhicris
Copy link
Copy Markdown
Contributor

Why

create_grpc_request builds proto::FunctionDeclaration from a rig_core::completion::ToolDefinition, but only forwards name and description. The ToolDefinition.parameters JSON schema is silently dropped, so Gemini receives every tool with no argument shape. In practice this turns every tool call into an argument-less invocation, which surfaces as the model either omitting required args or guessing.

The proto already exposes the destination field:

message FunctionDeclaration {
  string name        = 1;
  string description = 2;
  Schema parameters  = 3;   // ← never populated
  ...
}

Fixes #1710. Same field present in rig-gemini-grpc 0.2.0 through the current 0.2.5.

What

Add a small JSON Schema → proto::Schema converter (json_value_to_proto_schema / tool_parameters_to_proto_schema) local to rig-gemini-grpc::completion, and pipe tool.parameters through it where the FunctionDeclaration is built.

Conventions chosen to match the existing rig-core::providers::gemini implementation:

  • The empty-object schema {"type": "object", "properties": {}} (the default ToolDefinition.parameters for argument-less tools) is mapped to None rather than a vacuous Schema, so we don't emit properties: {} to the API for tools that genuinely take no arguments.
  • Null input also maps to None.
  • type/format/description/nullable/enum/items/properties/required are mapped 1:1; recursion handles nested arrays/objects.
  • The converter lives inside this crate (no rig-core schema-helper leak) and uses only serde_json + the generated proto types, so it doesn't widen the public API.

How validated

cargo test  -p rig-gemini-grpc --lib
  running 10 tests
  ...
  test result: ok. 10 passed; 0 failed; 0 ignored

cargo clippy -p rig-gemini-grpc --all-targets
  Finished `dev` profile [unoptimized + debuginfo] target(s)
  (no warnings, no errors)

cargo doc    -p rig-gemini-grpc --no-deps
  Generated target/doc/rig_gemini_grpc/index.html

Five new unit tests in crates/rig-gemini-grpc/src/completion.rs:

  • tool_params_empty_object_maps_to_none — preserves the existing "no-args" convention.
  • tool_params_null_maps_to_none — defensive coverage for a Null parameters value.
  • tool_params_object_with_scalar_properties_round_trips — checks type, required, nested properties types and descriptions.
  • tool_params_array_with_typed_items — recursive items handling.
  • tool_params_enum_strings_preserved — string enum round-trip.
  • create_grpc_request_populates_tool_parameters — end-to-end regression test that drives create_grpc_request with a ToolDefinition and asserts FunctionDeclaration.parameters is populated with the expected typed schema. This is the test that would have caught the original bug.

Out of scope

  • FunctionDeclaration.parameters_json_schema (field 6) — Gemini's newer JSON-Schema-passthrough field. The typed Schema path is what rig-core::providers::gemini uses today, so this PR stays on that path for consistency. A follow-up could add an opt-in to send the raw JSON schema as parameters_json_schema for callers that want to bypass the type mapping.
  • FunctionDeclaration.response (field 4) — tool response schemas. Not currently carried on ToolDefinition; out of scope here.
  • Composition (anyOf / oneOf / allOf) — rig-core::providers::gemini has additional flattening for these; the gRPC path can follow if real-world tools start tripping it, but bug(rig-gemini-grpc): tool parameter schemas dropped from FunctionDeclaration #1710's reproduction doesn't require it.

…olDefinition

create_grpc_request mapped ToolDefinition into proto::FunctionDeclaration
but forwarded only `name` and `description`, leaving `parameters` at the
default `None`. Every tool was therefore sent to Gemini with no argument
shape, degrading tool calls to argument-less invocations.

Add a small JSON Schema -> proto::Schema converter local to this crate
(no rig-core leak), and pipe `tool.parameters` through it inside
create_grpc_request. The empty-object schema
({"type": "object", "properties": {}}) still resolves to None to avoid
emitting a vacuous schema, matching the convention used by
rig-core::providers::gemini::completion.

Tests cover the empty/null shortcut, scalar object properties with
required, typed array items, string enums, and a request-level
assertion that exercises create_grpc_request end-to-end and would have
caught the original regression.

cargo test -p rig-gemini-grpc --lib
  10 passed; 0 failed; 0 ignored
cargo clippy -p rig-gemini-grpc --all-targets
  clean

Fixes 0xPlaygrounds#1710
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(rig-gemini-grpc): tool parameter schemas dropped from FunctionDeclaration

1 participant