Letta
Letta (formerly MemGPT) is a framework and server for building stateful agents with long-term memory. The Letta server has native OTLP export built in, but it speaks OTLP/gRPC only and exposes a single endpoint env var with no way to set auth headers. Logfire’s direct ingest is OTLP/HTTP, so the robust path is to run a small OpenTelemetry Collector that receives Letta’s gRPC traces and forwards them to Logfire over HTTP with your write token.
flowchart LR
L[Letta server] -- OTLP/gRPC :4317 --> C[OTel Collector]
C -- OTLP/HTTP + Authorization --> LF[Logfire]
# Letta server + Python client
pip install letta letta-client
# The collector runs as a container:
# docker pull otel/opentelemetry-collector-contrib
Create otel-collector-config.yaml:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317 # Letta exports here
exporters:
otlphttp/logfire:
endpoint: 'https://logfire-us.pydantic.dev' # use logfire-eu.pydantic.dev for the EU region
headers:
Authorization: '${LOGFIRE_WRITE_TOKEN}'
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlphttp/logfire]
# 1. Start the collector (forwards to Logfire)
export LOGFIRE_WRITE_TOKEN="your-logfire-write-token"
docker run -p 127.0.0.1:4317:4317 \
-v "$PWD/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml" \
-e LOGFIRE_WRITE_TOKEN \
otel/opentelemetry-collector-contrib
# 2. Start the Letta server pointed at the collector
export LETTA_OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
letta server
Then talk to the server with the client:
from letta_client import Letta
client = Letta(base_url='http://localhost:8283')
agent = client.agents.create(
model='openai/gpt-4o-mini',
embedding='openai/text-embedding-3-small',
memory_blocks=[
{'label': 'human', 'value': "The user's name is Will."},
{'label': 'persona', 'value': 'You are a helpful assistant.'},
],
)
response = client.agents.messages.create(
agent_id=agent.id,
messages=[{'role': 'user', 'content': 'Hello! Remember my name.'}],
)
for message in response.messages:
print(message)
Each request to the Letta server now produces traces (including the underlying LLM provider requests) that flow through the collector into Logfire.
You can keep an agent’s persona / system text in Prompt Management and fetch it with the Logfire SDK before creating the agent:
pip install 'logfire[variables]'
from letta_client import Letta
from pydantic import BaseModel
import logfire
logfire.configure()
class PersonaInputs(BaseModel):
tone: str
persona_var = logfire.template_var(
name='prompt__letta_persona',
type=str,
default='You are a helpful assistant.',
inputs_type=PersonaInputs,
)
with persona_var.get(PersonaInputs(tone='warm'), label='production') as resolved:
persona = resolved.value
client = Letta(base_url='http://localhost:8283')
agent = client.agents.create(
model='openai/gpt-4o-mini',
embedding='openai/text-embedding-3-small',
memory_blocks=[{'label': 'persona', 'value': persona}],
)
See Use Prompts in Your Application for the full workflow.