Skip to content

langroid

v0.65.10 Bugfix

This release fixes issues for SREs watching stability and regressions.

✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

agents ai chatgpt function-calling llm gpt-4
+10 more
gpt4 information-retrieval language-model llama llm-agent llm-framework local-llm multi-agent-systems openai-api retrieval-augmented-generation

Summary

AI summary

Fixed Gemini 3.x tool calls by faithfully preserving empty content as None instead of padding with a space.

Full changelog

0.65.10 — Faithful "no content" for LLM messages (fixes Gemini 3.x tool calls)

This release fixes tool calls with Gemini 3.x models (e.g.
gemini-3.5-flash-lite, gemini-3.6-flash) on Vertex AI, originally
diagnosed and fixed by @alexagr. Langroid now
carries an assistant turn's "no content" faithfully as None instead of
padding it to a single space, so tool-call turns no longer trip Gemini's
400 INVALID_ARGUMENT.

pip install -U langroid

The bug — a padded space breaks Gemini 3.x tool calls (#1062)

An assistant turn that is only a tool/function call has no text content.
ChatDocument.to_LLMMessage padded such empty content with a single space
(" ") "because some LLM APIs don't like an empty msg", so every stored
tool-call turn carried content=" ".

Gemini 3.x rejects an assistant turn that has both a tool/function call
and non-empty text content with 400 INVALID_ARGUMENT — breaking every
conversation on the turn that sends a tool result back to the model.

The fix — carry the response shape faithfully, don't fabricate content

Langroid now distinguishes "missing" (None, omitted on the wire) from
"present-but-empty" ("") end to end:

  • LLMResponse.message is now Optional[str]; a tool-only response keeps
    message=None rather than being coerced to "".
  • ChatDocument gains an explicit content_is_none flag (the content
    field itself stays a mandatory str), which is authoritative when
    reconstructing the message — a serialized/round-tripped tool-call turn
    cannot resurrect stale text alongside its calls.
  • ChatDocument.to_LLMMessage reproduces "no content" as
    LLMMessage.content=None (now Optional[str]) instead of " ".
  • LLMMessage.api_dict drops None content from the payload, and pads a
    lone space only when a message would otherwise be entirely empty
    (no content and no tool/function call) — the case older Gemini models
    reject.

None-safety guards were added for the consumers of the now-optional fields
(token counting, truncation, display callbacks, cached-response replay), with
regression tests across the LLMResponse → ChatDocument → LLMMessage
pipeline for both the tool_calls and legacy function_call shapes.

No action needed for existing code — this is a transparent fix. If you use
Gemini 3.x models on Vertex AI with tools, they now work.

Full Changelog: https://github.com/langroid/langroid/compare/0.65.9...0.65.10

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track langroid

Get notified when new releases ship.

Sign up free

About langroid

Harness LLMs with Multi-Agent Programming

All releases →

Related context

Earlier breaking changes

  • v0.65.9 MCP tool parameters now strictly validate enums, unions, and nested models.
  • v0.65.5 Blocks code‑execution, file, and network primitives in creation tools by default.
  • v0.65.5 Restricts retrieval tools to read‑only queries; write or admin clauses are rejected by default.
  • v0.65.3 Raw user messages containing tools registered with `enable_message(..., use=False, handle=True)` are now dropped instead of executed.
  • v0.65.2 Restricts eval'd expression builtins to a curated safe set, breaking code that relied on full Python builtins (e.g., __import__, open).

Beta — feedback welcome: [email protected]