Standalone Blocks
Memory blocks can be created independently and shared across multiple agents
Memory blocks are structured sections of an agent’s context window that persist across all interactions. They’re always visible to the agent while they are attached. This makes them perfect for storing information that agents need constant access to, like organizational policies, user preferences, or working memory.
One of the most powerful features of memory blocks is that they can be created independently and attached to or detached from agents at any time.
This allows you to:
By the end of this guide, you’ll understand how to create standalone memory blocks, attach them to agents, detach them to remove access, and re-attach them when needed.
You will need to install letta-client to interface with a Letta server:
bash TypeScript npm install @letta-ai/letta-client bash Python pip install letta-client
import { LettaClient } from "@letta-ai/letta-client";
// Initialize the Letta client using LETTA_API_KEY environment variableconst client = new LettaClient({ token: process.env.LETTA_API_KEY });
// If self-hosting, specify the base URL:// const client = new LettaClient({ baseUrl: "http://localhost:8283" });
// Create agent// API Reference: https://docs.letta.com/api-reference/agents/createconst agent = await client.agents.create({ name: "hello_world_assistant", model: "openai/gpt-4o-mini", // embedding: "openai/text-embedding-3-small", // Only set this if self-hosting});
console.log(`Created agent: ${agent.id}\n`);from letta_client import Lettaimport os
# Initialize the Letta client using LETTA_API_KEY environment variableclient = Letta(token=os.getenv("LETTA_API_KEY"))
# If self-hosting, specify the base URL:# client = Letta(base_url="http://localhost:8283")
# Create agent# API Reference: https://docs.letta.com/api-reference/agents/createagent = client.agents.create( name="hello_world_assistant", model="openai/gpt-4o-mini", # embedding="openai/text-embedding-3-small", # Only set this if self-hosting)
print(f"Created agent: {agent.id}\n")Created agent: agent-a1b2c3d4-e5f6-7890-abcd-ef1234567890
Memory blocks can be created independently of any agent. This allows you to share the same block across multiple agents or attach/detach blocks as needed.
In this example, we’ll create a standalone memory block storing information about Letta. We’ll include a code that you can use to get the agent to respond to indicate that it has access to information in the block.
When the block is attached, writing “The code is TimberTheDog1234!” will cause the agent to respond with “Access granted”. If the block is not attached, the agent will not have access to any content in the block and will likely be confused by the code.
// Create memory block storing information about Letta// API Reference: https://docs.letta.com/api-reference/blocks/createconst block = await client.blocks.create({ label: "organization", value: `Organization: LettaWebsite: https://www.letta.comDescription: Letta is a platform for building and running stateful agents.Code: TimberTheDog1234!
When users provide a code, you should check if it matches the code you haveavailable. If it matches, you should respond with "Access granted".`,});
console.log(`Created block: ${block.id}\n`);# Create memory block storing information about Letta# API Reference: https://docs.letta.com/api-reference/blocks/createblock = client.blocks.create( label="organization", value="""Organization: LettaWebsite: https://www.letta.comDescription: Letta is a platform for building and running stateful agents.Code: TimberTheDog1234!
When users provide a code, you should check if it matches the code you haveavailable. If it matches, you should respond with "Access granted".""",)
print(f"Created block: {block.id}\n")Created block: block-a1b2c3d4-e5f6-7890-abcd-ef1234567890
Now let’s attach the block to our agent. Attached blocks are injected into the agent’s context window and are available to the agent to use in its responses.
// Attach memory block to agent// API Reference: https://docs.letta.com/api-reference/agents/blocks/attachawait client.agents.blocks.attach(agent.id, block.id);
console.log(`Attached block ${block.id} to agent ${agent.id}\n`);# Attach memory block to agent# API Reference: https://docs.letta.com/api-reference/agents/blocks/attachagent = client.agents.blocks.attach( agent_id=agent.id, block_id=block.id,)
print(f"Attached block {block.id} to agent {agent.id}\n")The agent can now see what’s in the block. Let’s ask it about Letta to verify that it can see the general information in the block — the description, website, and organization name.
// Send a message to test the agent's knowledge// API Reference: https://docs.letta.com/api-reference/agents/messages/createconst response = await client.agents.messages.create(agent.id, { messages: [{ role: "user", content: "What is Letta?" }],});
for (const msg of response.messages) { if (msg.messageType === "assistant_message") { console.log(`Agent response: ${msg.content}\n`); }}# Send a message to test the agent's knowledge# API Reference: https://docs.letta.com/api-reference/agents/messages/createresponse = client.agents.messages.create( agent_id=agent.id, messages=[{"role": "user", "content": "What is Letta?"}],)
for msg in response.messages: if msg.message_type == "assistant_message": print(f"Agent response: {msg.content}\n")The agent will respond with general information about Letta:
Agent response: Letta is a platform designed for building and running stateful agents. You can find more information about it on their website: https://www.letta.com
Blocks can be detached from an agent, removing them from the agent’s context window. Detached blocks are not deleted and can be re-attached to an agent later.
// Detach the block from the agent// API Reference: https://docs.letta.com/api-reference/agents/blocks/detachawait client.agents.blocks.detach(agent.id, block.id);
console.log(`Detached block ${block.id} from agent ${agent.id}\n`);# Detach the block from the agent# API Reference: https://docs.letta.com/api-reference/agents/blocks/detachagent = client.agents.blocks.detach( agent_id=agent.id, block_id=block.id,)
print(f"Detached block {block.id} from agent {agent.id}\n")Let’s test the code that was in the block. The agent should no longer have access to it.
// Test that the agent no longer has access to the codeconst response2 = await client.agents.messages.create(agent.id, { messages: [{ role: "user", content: "The code is TimberTheDog1234!" }],});
for (const msg of response2.messages) { if (msg.messageType === "assistant_message") { console.log(`Agent response: ${msg.content}\n`); }}# Test that the agent no longer has access to the coderesponse = client.agents.messages.create( agent_id=agent.id, messages=[{"role": "user", "content": "The code is TimberTheDog1234!"}],)
for msg in response.messages: if msg.message_type == "assistant_message": print(f"Agent response: {msg.content}\n")Agent response: It seems like you've provided a code or password. If thisis sensitive information, please ensure you only share it with trusted partiesand in secure environments. Let me know how I can assist you further!Let’s re-attach the block to restore the agent’s access to the information.
// Re-attach the block to the agentawait client.agents.blocks.attach(agent.id, block.id);
console.log(`Re-attached block ${block.id} to agent ${agent.id}\n`);
// Test the code againconst response3 = await client.agents.messages.create(agent.id, { messages: [{ role: "user", content: "The code is TimberTheDog1234!" }],});
for (const msg of response3.messages) { if (msg.messageType === "assistant_message") { console.log(`Agent response: ${msg.content}\n`); }}# Re-attach the block to the agentagent = client.agents.blocks.attach( agent_id=agent.id, block_id=block.id,)
print(f"Re-attached block {block.id} to agent {agent.id}\n")
# Test the code againresponse = client.agents.messages.create( agent_id=agent.id, messages=[{"role": "user", "content": "The code is TimberTheDog1234!"}],)
for msg in response.messages: if msg.message_type == "assistant_message": print(f"Agent response: {msg.content}\n")Agent response: Access granted. How can I assist you further?
Here’s the full code in one place that you can run:
import { LettaClient } from "@letta-ai/letta-client";
async function main() { // Initialize client const client = new LettaClient({ token: process.env.LETTA_API_KEY });
// Create agent const agent = await client.agents.create({ name: "hello_world_assistant", model: "openai/gpt-4o-mini", });
console.log(`Created agent: ${agent.id}\n`);
// Create standalone memory block const block = await client.blocks.create({ label: "organization", value: `Organization: Letta
Website: https://www.letta.comDescription: Letta is a platform for building and running stateful agents.Code: TimberTheDog1234!
When users provide a code, you should check if it matches the code you haveavailable. If it matches, you should respond with "Access granted".`, });
console.log(`Created block: ${block.id}\n`);
// Attach block to agent await client.agents.blocks.attach(agent.id, block.id); console.log(`Attached block to agent\n`);
// Test agent with block attached let response = await client.agents.messages.create(agent.id, { messages: [{ role: "user", content: "What is Letta?" }], }); console.log(`Agent response: ${response.messages[0].content}\n`);
// Detach block await client.agents.blocks.detach(agent.id, block.id); console.log(`Detached block from agent\n`);
// Test agent without block response = await client.agents.messages.create(agent.id, { messages: [{ role: "user", content: "The code is TimberTheDog1234!" }], }); console.log(`Agent response: ${response.messages[0].content}\n`);
// Re-attach block await client.agents.blocks.attach(agent.id, block.id); console.log(`Re-attached block to agent\n`);
// Test agent with block re-attached response = await client.agents.messages.create(agent.id, { messages: [{ role: "user", content: "The code is TimberTheDog1234!" }], }); console.log(`Agent response: ${response.messages[0].content}\n`);}
main();from letta_client import Lettaimport os
# Initialize clientclient = Letta(token=os.getenv("LETTA_API_KEY"))
# Create agentagent = client.agents.create( name="hello_world_assistant", model="openai/gpt-4o-mini",)
print(f"Created agent: {agent.id}\n")
# Create standalone memory blockblock = client.blocks.create( label="organization", value="""Organization: LettaWebsite: https://www.letta.comDescription: Letta is a platform for building and running stateful agents.Code: TimberTheDog1234!
When users provide a code, you should check if it matches the code you haveavailable. If it matches, you should respond with "Access granted".""",)
print(f"Created block: {block.id}\n")
# Attach block to agentagent = client.agents.blocks.attach( agent_id=agent.id, block_id=block.id,)print(f"Attached block to agent\n")
# Test agent with block attachedresponse = client.agents.messages.create( agent_id=agent.id, messages=[{"role": "user", "content": "What is Letta?"}],)print(f"Agent response: {response.messages[0].content}\n")
# Detach blockagent = client.agents.blocks.detach( agent_id=agent.id, block_id=block.id,)print(f"Detached block from agent\n")
# Test agent without blockresponse = client.agents.messages.create( agent_id=agent.id, messages=[{"role": "user", "content": "The code is TimberTheDog1234!"}],)print(f"Agent response: {response.messages[0].content}\n")
# Re-attach blockagent = client.agents.blocks.attach( agent_id=agent.id, block_id=block.id,)print(f"Re-attached block to agent\n")
# Test agent with block re-attachedresponse = client.agents.messages.create( agent_id=agent.id, messages=[{"role": "user", "content": "The code is TimberTheDog1234!"}],)print(f"Agent response: {response.messages[0].content}\n")Standalone Blocks
Memory blocks can be created independently and shared across multiple agents
Dynamic Access Control
Attach and detach blocks to control what information an agent can access
Block Persistence
Detached blocks are not deleted and can be re-attached at any time
Shared Memory
The same block can be attached to multiple agents, enabling shared knowledge
Attach a block with credentials or sensitive data only when needed, then detach it to prevent unauthorized access.
Create a single block with organizational knowledge and attach it to multiple agents to ensure consistency.
Detach blocks related to one task and attach blocks for another, allowing an agent to switch contexts efficiently.
Give different agents access to different blocks based on their roles or permissions.
Memory Blocks Guide
Learn more about memory blocks, including how to update them and manage their lifecycle