Skip to content

fix(kosong): make Gemini (google-genai/vertexai) tool-calling work#1360

Open
powerfooI wants to merge 1 commit into
MoonshotAI:mainfrom
powerfooI:fix/gemini-tool-calling
Open

fix(kosong): make Gemini (google-genai/vertexai) tool-calling work#1360
powerfooI wants to merge 1 commit into
MoonshotAI:mainfrom
powerfooI:fix/gemini-tool-calling

Conversation

@powerfooI

Copy link
Copy Markdown

Related Issue

No existing issue — this is a clear, reproducible bug fix with a focused diff (allowed without prior discussion per CONTRIBUTING). Problem described below.

Problem

Gemini tool-calling is broken for both google-genai and vertexai:

  1. Empty tool specs → MALFORMED_FUNCTION_CALL. The provider builds function declarations with snake_case keys (function_declarations, parameters_json_schema) and content parts with function_call / function_response / thought_signature. The @google/genai SDK expects camelCase, so it drops these keys and sends empty tool objects (tools: [{}]) on the wire. Gemini then responds with finishReason: MALFORMED_FUNCTION_CALL and empty content.

  2. Multi-turn fails with missing thought_signature. Once tools are populated, Gemini 3.x requires the thoughtSignature to be echoed back on later turns. The provider captures it into ToolCall.extras.thought_signature_b64, but LoopToolCallEvent has no extras field and the ContextMemory / transcript reconstructors rebuild tool calls without it, so the signature is lost and continuations are rejected.

The existing google-genai tests mock generateContentStream and assert the snake_case object passed into the SDK, so the real serialization was never exercised and the bug went uncaught.

What changed

  • packages/kosong/src/providers/google-genai.ts — emit the camelCase keys the SDK expects: functionDeclarations, parametersJsonSchema, functionCall, functionResponse, thoughtSignature.
  • packages/agent-core — add extras to LoopToolCallEvent, dispatch toolCall.extras in dispatchToolCall, and copy extras when rebuilding tool calls in ContextMemory (agent/context) and the transcript service, so thoughtSignature round-trips across turns.
  • packages/kosong/test/google-genai.test.ts — updated to assert the camelCase keys the SDK requires.

Verified end-to-end against a real Gemini endpoint (gemini-3.1-pro-preview): multi-turn tool-using tasks (create file → shell command → read back) now complete for both google-genai and vertexai. pnpm typecheck, pnpm lint (0 errors), and the kosong/agent-core test suites pass.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset. (changeset added manually)
  • Ran gen-docs skill, or this PR needs no doc update. (no user-facing doc change)

The Google GenAI provider built function declarations and content parts with
snake_case keys (function_declarations, parameters_json_schema, function_call,
function_response, thought_signature). The @google/genai SDK expects camelCase,
so it silently dropped those keys and sent empty tool specs, causing Gemini to
return MALFORMED_FUNCTION_CALL. Separately, tool-call thought_signature extras
captured from responses were dropped in the agent-core tool-call event pipeline
(LoopToolCallEvent had no extras; the context/transcript reconstructors rebuilt
tool calls without them), so multi-turn Gemini 3.x tool use failed with
"missing thought_signature".

- kosong/google-genai: emit camelCase functionDeclarations / parametersJsonSchema
  / functionCall / functionResponse / thoughtSignature.
- agent-core: add extras to LoopToolCallEvent, dispatch toolCall.extras, and copy
  extras when rebuilding tool calls in ContextMemory and the transcript service.
- Update kosong google-genai tests to assert the camelCase the SDK requires.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ce8bae6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@moonshot-ai/kimi-code Patch
@moonshot-ai/kimi-code-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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.

1 participant