letta-ai/letta-agent-sdk

The Letta Agent SDK is the SDK for stateful agents. Each agent has its own identity and long-term memory, and keeps both across conversations, models, and the computers it runs on.

TypeScript

100

262 commits

updated Sep 22, 2026

See the code

README

Letta Agent SDK

npm Discord

The SDK for stateful agents: create an agent once, then resume it from anywhere. Each agent has its own identity and long-term memory, and keeps both across conversations, models, and the computers it runs on.

Read the documentation for guides and the full API reference.

Quick start

npm install @letta-ai/letta-agent-sdk
import { LettaAgentClient } from "@letta-ai/letta-agent-sdk";

const client = new LettaAgentClient({ backend: "cloud" });

// Create the agent once...
const agentId = await client.createAgent({
  systemPrompt: "You are Nora, a research analyst who tracks our competitors.",
  memfs: true,
});

// ...then resume it, from anywhere, for as long as it lives.
await using session = client.resumeSession(agentId);

await session.send("What changed since last week?");
for await (const message of session.stream()) {
  if (message.type === "assistant") process.stdout.write(message.content);
}

Local and remote management clients can use await using client = new LettaAgentClient(...), or call await client.close() explicitly. Client disposal closes its pooled management connection and any local App Server it started. Sessions are independently owned and must still be closed separately.

Latency-sensitive applications can initialize the runtime and transport before the first user action without fetching transcript history or invoking the model:

const session = client.resumeSession(conversationId);
await session.ready();
await session.send(message);

ready() is idempotent and safe to call concurrently. SDKResultMessage.durationMs measures the tracked turn and excludes session initialization; measure ready() separately when startup latency matters.

For a simple question that should not create or use an agent, call query(). It creates an agent-free ephemeral conversation from the supplied model and system prompt, streams the turn, and closes the runtime when iteration ends:

for await (const message of client.query({
  prompt: "What is the capital of France?",
  options: {
    model: "openai/gpt-5.6-luna",
    system: "Answer directly and concisely.",
  },
})) {
  if (message.type === "assistant") process.stdout.write(message.content);
}

query() requires an API-backed App Server. For backend: "local", set appServer.harnessBackend: "api"; the default local harness backend does not store agent-free conversations.

Cloud queries require an explicit connected computer. Local and remote clients run the ephemeral conversation through their App Server.

Set LETTA_API_KEY for the cloud backend. See the quickstart for the local and self-hosted paths.

Where your agents run

One interface, three backends:

BackendAgent stateTools execute
"cloud"Hosted by LettaA managed sandbox, or a computer you connect
"local"On this machine*On this machine*
"remote"Your App ServerOn your App Server machine

* "this machine" refers to the machine that the SDK code itself is running on

Browser, Expo, and React Native applications import from @letta-ai/letta-agent-sdk/client, which does not require Node and supports the cloud and remote backends. See Deployment.

Examples

Runnable applications live in examples/. Start with the examples guide, which orders the demos by concept and lists their setup and side effects. See the React chat template for a more complete custom UI.

Contributing

Development conventions for this repository are in AGENTS.md.


Made with 💜 in San Francisco

Contributors

cpacker

77 commits

just-cameron

38 commits

dependabot[bot]

19 commits

letta-ai/letta-agent-sdk

The Letta Agent SDK is the SDK for stateful agents. Each agent has its own identity and long-term memory, and keeps both across conversations, models, and the computers it runs on.

TypeScript

100

262 commits

updated Sep 22, 2026

See the code

README

Letta Agent SDK

npm Discord

The SDK for stateful agents: create an agent once, then resume it from anywhere. Each agent has its own identity and long-term memory, and keeps both across conversations, models, and the computers it runs on.

Read the documentation for guides and the full API reference.

Quick start

npm install @letta-ai/letta-agent-sdk
import { LettaAgentClient } from "@letta-ai/letta-agent-sdk";

const client = new LettaAgentClient({ backend: "cloud" });

// Create the agent once...
const agentId = await client.createAgent({
  systemPrompt: "You are Nora, a research analyst who tracks our competitors.",
  memfs: true,
});

// ...then resume it, from anywhere, for as long as it lives.
await using session = client.resumeSession(agentId);

await session.send("What changed since last week?");
for await (const message of session.stream()) {
  if (message.type === "assistant") process.stdout.write(message.content);
}

Local and remote management clients can use await using client = new LettaAgentClient(...), or call await client.close() explicitly. Client disposal closes its pooled management connection and any local App Server it started. Sessions are independently owned and must still be closed separately.

Latency-sensitive applications can initialize the runtime and transport before the first user action without fetching transcript history or invoking the model:

const session = client.resumeSession(conversationId);
await session.ready();
await session.send(message);

ready() is idempotent and safe to call concurrently. SDKResultMessage.durationMs measures the tracked turn and excludes session initialization; measure ready() separately when startup latency matters.

For a simple question that should not create or use an agent, call query(). It creates an agent-free ephemeral conversation from the supplied model and system prompt, streams the turn, and closes the runtime when iteration ends:

for await (const message of client.query({
  prompt: "What is the capital of France?",
  options: {
    model: "openai/gpt-5.6-luna",
    system: "Answer directly and concisely.",
  },
})) {
  if (message.type === "assistant") process.stdout.write(message.content);
}

query() requires an API-backed App Server. For backend: "local", set appServer.harnessBackend: "api"; the default local harness backend does not store agent-free conversations.

Cloud queries require an explicit connected computer. Local and remote clients run the ephemeral conversation through their App Server.

Set LETTA_API_KEY for the cloud backend. See the quickstart for the local and self-hosted paths.

Where your agents run

One interface, three backends:

BackendAgent stateTools execute
"cloud"Hosted by LettaA managed sandbox, or a computer you connect
"local"On this machine*On this machine*
"remote"Your App ServerOn your App Server machine

* "this machine" refers to the machine that the SDK code itself is running on

Browser, Expo, and React Native applications import from @letta-ai/letta-agent-sdk/client, which does not require Node and supports the cloud and remote backends. See Deployment.

Examples

Runnable applications live in examples/. Start with the examples guide, which orders the demos by concept and lists their setup and side effects. See the React chat template for a more complete custom UI.

Contributing

Development conventions for this repository are in AGENTS.md.


Made with 💜 in San Francisco

Contributors

cpacker

77 commits

just-cameron

38 commits

dependabot[bot]

19 commits

Languages

TypeScript

100.0%