Skip to content

langroid

v0.65.9 Breaking

This release includes 1 breaking change for platform teams planning a safe upgrade.

✓ 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

ReleasePort's take

Light signal
editorial:auto 13d

MCP tool parameters now strictly validate enums, unions, and nested models; LLM retry logic fails fast on non‑retryable 4xx errors instead of using exponential backoff.

Why it matters: Strict validation of MCP tool parameters eliminates misconfiguration risks; failing fast on unretryable 4xx LLM responses prevents unnecessary latency and resource waste.

Summary

AI summary

Updates https://github.com/alexagr, retryable, and https://github.com/langroid/langroid/pull/1055 across a mixed release.

Changes in this release

Breaking High

MCP tool parameters now strictly validate enums, unions, and nested models.

MCP tool parameters now strictly validate enums, unions, and nested models.

Source: llm_adapter@2026-07-13

Confidence: high

Bugfix Medium

Fail fast on non‑retryable 4xx LLM errors instead of retrying with exponential backoff.

Fail fast on non‑retryable 4xx LLM errors instead of retrying with exponential backoff.

Source: llm_adapter@2026-07-13

Confidence: high

Full changelog

0.65.9 — Precise MCP tool-parameter types, and fail-fast on non-retryable LLM errors

Two improvements this release, both originally contributed by
@alexagr: MCP tool parameters now map to precise
Python types — so they validate correctly and the LLM sees accurate schemas —
and the LLM retry logic now fails fast on non-retryable 4xx errors instead of
retrying them with exponential backoff.

pip install -U langroid

Precise MCP tool-parameter types (#1059)

When Langroid builds a ToolMessage from an MCP tool,
FastMCPClient._schema_to_field converts each parameter's JSON Schema into a
Python type. Several common constructs were previously dropped — falling
through to a plain scalar or to Any — so the generated tool lost type
information both for validation and in the schema the LLM sees. They now map to
precise types:

  • enum / consttyping.Literal.
  • anyOf / oneOftyping.Union; a {"type": "null"} branch (or an
    optional parameter) makes it Optional — the common Optional[...] shape
    fastmcp emits.
  • allOf with a single subschema → that subschema; a multi-schema intersection
    falls back to Any.
  • $ref into the tool's $defs (pydantic-model params, including inside unions
    and array items) → a nested pydantic model, with reference cycles degrading
    the cyclic edge to Any.

This release also fixes a Pydantic v1→v2 regression in
ToolMessage.llm_function_schema(): the nested-model schema cleanup keyed off
v1's "definitions", but v2 emits "$defs", so under Langroid's v2 the cleanup
silently no-op'd — leaking purpose / id / exclude and an unconstrained
request into nested ToolMessage schemas sent to the LLM. It now tracks the
v2 key.

Why it matters:

  • Validation — out-of-set enum values and wrong-type union values now
    raise ValidationError instead of being silently accepted.
  • Better LLM grounding — pydantic re-emits enum, anyOf, and nullability
    in the schema, so the model receives exact parameter types instead of
    "string" / "any".

Behavior change: MCP tools with enum / union / nested-model params are now
strictly validated; a value that violates a (previously dropped) constraint now
raises ValidationError. Well-formed calls are unaffected.

Fail fast on non-retryable 4xx LLM errors (#1058)

The retry decorators (retry_with_exponential_backoff and its async variant)
decided non-retryability by substring-matching str(e). But a native
OpenAI-SDK error stringifies to Error code: 404 - ..., which does not
contain the class name, so native 403 / 404 errors — e.g. a retired or
unknown model on an OpenAI-compatible endpoint such as Gemini — slipped past the
guard and were retried with exponential backoff instead of failing immediately.

A type-based guard now catches the non-retryable 4xx errors
(BadRequestError 400, AuthenticationError 401, PermissionDeniedError 403,
NotFoundError 404, UnprocessableEntityError 422) in both the sync and async
paths and raises them immediately. This also closes two latent gaps: the async
path was missing 422 handling and neither path handled 403. Retryable errors
(429, 5xx, timeouts) are unaffected, and the substring guard is retained as a
fallback for LiteLLM-proxy-wrapped errors.

Behavior change: a non-retryable 4xx error now fails fast instead of after
several backoff retries — faster, clearer failures, with no change for
transient (retryable) errors.

Credit

Both improvements were originally contributed by
@alexagr in
#1055 and
#1057; this release ships them
with added hardening, tests, and docs.

Upgrade

pip install -U langroid

Full changelog:
0.65.8...0.65.9

Breaking Changes

  • MCP tool parameters with `enum`, `anyOf`, `oneOf`, or nested-model JSON Schema now strictly validate; previously dropped constraints no longer silently accept invalid values.

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.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).
  • v0.65.1 Rejects additional PostgreSQL-specific obfuscations of dangerous functions like `pg_read_file` in `SQLChatAgent`.

Beta — feedback welcome: [email protected]