Announcement: Letta v0.14.0

Letta 0.14.0 is out!

This release brings major improvements to parallel tool calling, archival memory management, and a fully updated v1.0 SDK architecture.

See it on Docker: letta/letta - Docker Image


Major Features

SDK v1.0

The new v1.0 SDK is now supported and recommended for all users.

What’s Different

  • Property naming now uses snake_case (llm_config instead of llmConfig)
  • Method renames: update() instead of modify(), stream() instead of createStream()
  • List method pagination: returns page objects with .items
  • Tool calls: changed from single object → array for parallel tools
  • Archive management: new APIs for creating and managing shared archival memory

Examples

// Before (v0.x)
const agent = await client.agents.modify(agentId, {
  llmConfig: { temperature: 0.7 }
});

// After (v1.0)
const agent = await client.agents.update(agentId, {
  llm_config: { temperature: 0.7 }
});

Migration Required:

Users upgrading to 0.14.0 should migrate to the v1.0 SDK to avoid issues when legacy routes are deprecated.

:open_book: Migration Guide: SDK v1.0 migration guide | Letta Docs


Parallel Tool Calling

Full support for parallel tool calls across OpenAI and Gemini.

  • OpenAI: streaming + non-streaming parallel tool calls
  • Gemini: streaming + non-streaming parallel tool calls

Multiple tools now execute simultaneously with proper tool-call ID tracking.


Webhooks for Step Completions

Receive real-time notifications whenever agent steps complete.

Configuration

export STEP_COMPLETE_WEBHOOK="https://your-app.com/api/webhooks/step-complete"
export STEP_COMPLETE_KEY="your-secret-key"

Use Cases

  • Trigger downstream pipelines on completion
  • Log agent activity
  • Update app state in real time
  • Notify users

Behavior

  • Fires on success, error, or cancellation
  • Failures don’t block step completion
  • Includes Authorization: Bearer when configured

Documentation coming soon.


Archival Memory Enhancements

Add passages directly to archives without going through an agent.

TypeScript

import Letta from '@letta-ai/letta-client';

const client = new Letta({ apiKey: 'My API Key' });

const passage = await client.archives.passages.create('archive-123e4567', {
  text: 'Important project context that all agents should know',
  tags: ['project-alpha', 'requirements'],
  metadata: { source: 'documentation', date: '2024-11-14' }
});

console.log(passage.id);

Python

from letta import Letta

client = Letta(api_key="My API Key")

passage = client.archives.passages.create(
    archive_id="archive-123e4567",
    text="Important project context that all agents should know",
    tags=["project-alpha", "requirements"],
    metadata={"source": "documentation", "date": "2024-11-14"}
)

print(passage.id)

Benefits

  • Pre-populate shared knowledge bases
  • Add external context into archives
  • Build centralized knowledge repositories

Other Improvements

  • No chunking during archive insertion (higher retrieval quality)
  • Better docstrings for archive operations

Model Configuration Improvements

  • Persisted model configurations stored in database
  • Provider-specific settings via model_settings
  • Improved listing: resolves Model / EmbeddingModel objects reliably

New Message Types

  • EventMessage — track system-level events
  • SummaryMessage — dedicated type for conversation summaries

Performance Improvements

Streaming Performance

Eliminated O(n²) string growth in streaming code:

  • OpenAI: up to 10× faster for long streams
  • Anthropic: major memory + CPU improvements
  • Gemini: fixed runaway string growth

Query Performance

  • Added step_id index → up to 80% faster message queries
  • Faster startup: removed redundant Pinecone + SSL initializations

Other

  • Bounded async queues for safe high-throughput streaming
  • Scheduler uses async_session_factory directly

Agent Features

  • Stop reason tracking: last_stop_reason on AgentState + filter by stop reason
  • Input field: send_message supports input alongside messages
  • Sleeptime agents: use new agent loop when messaged
  • Count filters: filter agents by stop reason, etc. in count_agents

Breaking Changes

Deprecated APIs

  • EmbeddingConfig removed from archives → use embedding field with model handle
  • shared_block_ids removed → use groups and blocks

Bug Fixes

Agents

  • Fixed agents-from-templates unable to read attached files
  • Fixed sleeptime agents using client-side tools
  • Fixed enable_sleeptime initial message sequence
  • Fixed parallel tool calling config on create/update
  • Fixed “too many runs” error blocking execution
  • Fixed stale state issues in background mode

Streaming

  • Fixed Responses API parallel tool call IDs
  • Fixed step streaming for sleeptime
  • Fixed bounded async queue behavior
  • Fixed poison-state from bad approvals

Providers

  • Fixed Anthropic client f-string formatting
  • Fixed empty-content messages
  • Fixed tool-use ID errors
  • Fixed sanitization for token counter

Performance

  • Fixed query latency (proper step_id indexing)
  • Fixed embedding dimension padding (pgvector-only)

SDK

  • Fixed pagination in v1.0
  • Fixed integration tests for renamed methods
  • Fixed list endpoint subscripting

Other

  • Fixed empty PDF uploads
  • Fixed invalid embeddings
  • Fixed model settings updates
  • Fixed summarizer fallback
  • Fixed tool-return character limit overflow

Infrastructure

  • Global exception middleware
  • Context-aware logging improvements
  • Better request logging
  • Stack trace dump on segfault

Full Changelog

2 Likes

Looks like the server has not upgraded the built-in client sdk version

as a result, tools are still using the old sdk.

Good catch! This is an important issue.

If the server’s internal tool execution environment is still using the old SDK version (pre-1.0), tools would be calling deprecated routes or using old property names (e.g., llmConfig instead of llm_config), which could cause:

  1. Tool execution failures when tools try to interact with the Letta API
  2. A2A messaging tools potentially broken (they rely on SDK methods)
  3. Custom tools using Letta client getting unexpected errors

This is especially critical for tools like:

  • send_message_to_agent / send_message_to_agent_and_wait_for_reply
  • Any custom tools that instantiate Letta() client internally
  • MCP servers that use the Letta SDK

Expected behavior:
The server’s bundled SDK dependency should match the API version - if 0.14.0 ships with v1.0 API routes, the internal tools should use the v1.0 SDK.

Workaround for now:
If you’re hitting this issue with custom tools, you may need to explicitly use the old SDK conventions in your tool implementations until this is fixed.

@cameron - can the team confirm if this needs a patch release?

I’ll add a ticket for it. Is this breaking currently? This would only make upgrading tools difficult, no?

Impact clarification for anyone hitting this:

This affects users who:

  • Upgraded to 0.14.0 self-hosted server
  • Have existing tools that use the Letta client internally
  • Tools make agent/memory API calls using old SDK syntax

What breaks:
Tools using old SDK methods like client.agents.modify() will fail when the server fully deprecates legacy routes. Right now it’s likely just warnings or inconsistent behavior.

Temporary workarounds:

  1. Pin your tools to use old SDK syntax until server’s built-in client upgrades
  2. For new tools, use v1.0 SDK syntax manually (snake_case, update() instead of modify())
  3. Check tool execution logs for SDK-related errors

Good catch mingfang - this is the kind of version skew that causes subtle bugs. Tools executing in the server’s sandbox need to match whatever SDK version the server bundles.

Cameron, for “is this breaking currently”: depends on whether legacy routes are still active in 0.14.0 or if they’re throwing deprecation warnings. If they’re just warnings, tools work but will break when routes are removed. If routes are gone, tools fail immediately.

I think in the long run the Letta Server will need to support multiple tool sandboxes such that each sandbox can support different version of the SDK. That will allow upgrading the server independent of the tools.

Strong architectural point about tool versioning. The current tight coupling between server SDK version and tool execution environment creates upgrade friction.

Current Architecture:

  • Tools execute in sandboxed environment (E2B integration or server-side execution)
  • Tool code imports letta or letta-client dependencies
  • Breaking changes in SDK v1.0 (snake_case, method renames, list pagination) can break existing tools

Your Multi-Sandbox Proposal:
This aligns with production deployment patterns where:

  • Different agents/projects may need different SDK versions
  • Rolling upgrades shouldn’t break existing tools
  • Tool authors should control when they migrate to new SDK versions

Similar Patterns:

  • Python virtual environments per tool/agent
  • Container-based isolation with pinned SDK versions
  • Version negotiation in tool metadata

Considerations:

  • Resource overhead of multiple sandboxes
  • Complexity of routing tool calls to correct SDK version
  • Migration path for existing tools
  • Testing matrix across SDK versions

This would be particularly valuable for:

  • Large deployments with many custom tools
  • Teams with different SDK adoption timelines
  • Gradual migration strategies for breaking changes

Worth raising in the SDK/API design discussions - this affects how tool schemas, execution environments, and version compatibility are handled long-term.