@letta-ai/letta-code 0.25.11 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -28
- package/dist/types/protocol.d.ts +2 -2
- package/docs/nix.md +105 -0
- package/docs/plans/discord-channel-policy-consolidation.md +35 -0
- package/letta.js +7934 -7402
- package/package.json +4 -2
- package/scripts/check-layer-boundaries.js +23 -3
- package/scripts/run-unit-tests.cjs +0 -1
- package/skills/initializing-memory/SKILL.md +1 -2
package/README.md
CHANGED
|
@@ -15,33 +15,64 @@ Letta Code is a frontier coding agent and can also be used as a long-lived perso
|
|
|
15
15
|

|
|
16
16
|
|
|
17
17
|
## Feature Overview
|
|
18
|
+
|
|
18
19
|
> [!TIP]
|
|
19
20
|
> Letta Code agents are designed to be self-configuring. If you want to configure something (e.g. skills, behavior, hooks, permissions), try asking your agent to do it for you.
|
|
20
21
|
|
|
21
22
|
| Feature | Description |
|
|
22
23
|
|---|---|
|
|
23
|
-
| [Self-improvement & Learning](https://docs.letta.com/letta-code/self-improvement) | Agents programmatically rewrite their context to improve and adapt over time, including system prompt learning (through [memory blocks](https://www.letta.com/blog/memory-blocks)) and [skill learning](https://www.letta.com/blog/skill-learning). Configure periodic dreaming with `/sleeptime`, audit memory quality with `/doctor`, and view memory with `/palace`
|
|
24
|
+
| [Self-improvement & Learning](https://docs.letta.com/letta-code/self-improvement) | Agents programmatically rewrite their context to improve and adapt over time, including system prompt learning (through [memory blocks](https://www.letta.com/blog/memory-blocks)) and [skill learning](https://www.letta.com/blog/skill-learning). Configure periodic dreaming with `/sleeptime`, audit memory quality with `/doctor`, and view memory with `/palace` |
|
|
24
25
|
| [Message search](https://docs.letta.com/letta-code/conversation-search) | Search across all messages and agents with `/search`. Agent can also search their own conversations or the conversations of other agents |
|
|
25
26
|
| [MemFS](https://docs.letta.com/letta-code/memfs) | All context (including memory blocks) is tracked via git. Sync context to a custom GitHub repository by setting `/memory-repository set git@github.com:...` |
|
|
26
27
|
| [Skills](https://docs.letta.com/letta-code/skills) | Loads global skills (`~/.letta`), project-scoped skills (`.agents/skills`), and agent-scoped skills (stored in MemFS). View skills with `/skills` and create with `/skill-creator` |
|
|
27
|
-
| [Subagents & Multi-agent](https://docs.letta.com/letta-code/subagents) | Call built-in subagents (general-purpose, forked, recall, history-analyzer) async or sync. Agents can call any other agent (including themselves) as subagents
|
|
28
|
+
| [Subagents & Multi-agent](https://docs.letta.com/letta-code/subagents) | Call built-in subagents (general-purpose, forked, recall, history-analyzer) async or sync. Agents can call any other agent (including themselves) as subagents |
|
|
28
29
|
| [Messaging Integrations](https://docs.letta.com/letta-code/channels) | Chat with the same agent from Slack, Telegram, your browser (chat.letta.com) including mobile, and through [custom channels](https://github.com/letta-ai/skills/blob/main/letta/creating-letta-code-channels/SKILL.md) |
|
|
29
30
|
| [Hooks](https://docs.letta.com/letta-code/hooks) | Run custom scripts at key points of agent execution to automate workflows |
|
|
30
31
|
| [Permissions](https://docs.letta.com/letta-code/permissions) | Set permission modes and customize what actions are auto-approved or auto-denied |
|
|
31
32
|
| [Crons & Schedules](https://docs.letta.com/letta-code/scheduling) | Configure heartbeats and crons, and let agents work across time with self-managed schedules |
|
|
32
|
-
| [Remote & Multi-Env](https://docs.letta.com/letta-code/client-server-architecture) | Agents work across multiple environments. Make any machine available as a remote environment by running `letta server --env-name "..."
|
|
33
|
-
| [Secrets](https://docs.letta.com/letta-code/secrets) | Make secrets available as environment variables (across machines) while obfuscating their values from context |
|
|
33
|
+
| [Remote & Multi-Env](https://docs.letta.com/letta-code/client-server-architecture) (requires Constellation login) | Agents work across multiple environments. Make any machine available as a remote environment by running `letta server --env-name "..."` |
|
|
34
|
+
| [Secrets](https://docs.letta.com/letta-code/secrets) (requires Constellation login) | Make secrets available as environment variables (across machines) while obfuscating their values from context |
|
|
34
35
|
|
|
35
36
|
See the full list of slash commands in our [documentation](https://docs.letta.com/letta-code/slash-commands).
|
|
36
37
|
|
|
37
38
|
## Get started
|
|
39
|
+
|
|
38
40
|
Install the package via [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm):
|
|
41
|
+
|
|
39
42
|
```bash
|
|
40
43
|
npm install -g @letta-ai/letta-code
|
|
41
44
|
```
|
|
42
|
-
Navigate to your project directory and run `letta` (see various command-line options [on the docs](https://docs.letta.com/letta-code/commands)).
|
|
43
45
|
|
|
44
|
-
|
|
46
|
+
Navigate to your project directory and run `letta` (see command-line options [in the docs](https://docs.letta.com/letta-code/commands)).
|
|
47
|
+
|
|
48
|
+
On first run, choose how you want to start:
|
|
49
|
+
|
|
50
|
+
* **Proceed locally** keeps agent state on this device. This is the local-first path and does not require a Constellation login.
|
|
51
|
+
* **Login to Constellation** syncs agent state through Constellation so you can access the same agents from `chat.letta.com`, the desktop app, and other machines — and agents can work across multiple machines.
|
|
52
|
+
|
|
53
|
+
Run `/connect` to configure your own LLM API keys (OpenAI / ChatGPT, Anthropic, Z.ai coding plan, etc.), and use `/model` to swap models.
|
|
54
|
+
|
|
55
|
+
You can also download the [**desktop app**](https://docs.letta.com/letta-code/desktop-app) for macOS, Windows, and Linux. Agents created in the CLI are available via the desktop app, and vice versa.
|
|
56
|
+
|
|
57
|
+
## Local mode
|
|
58
|
+
|
|
59
|
+
Local mode runs an embedded stateful agent server inside Letta Code. Agents, conversations, memory, provider connections, and secrets are stored on your machine.
|
|
60
|
+
|
|
61
|
+
You can enter local mode from the first-run setup menu, or explicitly with:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
letta --backend local
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Connect a provider from inside the TUI with `/connect`, or from the shell with `letta --backend local connect`:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
letta --backend local connect anthropic --api-key "$ANTHROPIC_API_KEY"
|
|
71
|
+
letta --backend local connect ollama
|
|
72
|
+
letta --backend local connect lmstudio
|
|
73
|
+
letta --backend local connect llama-cpp
|
|
74
|
+
letta --backend local connect chatgpt
|
|
75
|
+
```
|
|
45
76
|
|
|
46
77
|
For slow local inference servers, configure a provider-level timeout when connecting. For example, LM Studio-compatible llama-server backends that need up to 10 minutes for large-context compaction can use:
|
|
47
78
|
|
|
@@ -51,46 +82,72 @@ letta --backend local connect lmstudio --base-url http://127.0.0.1:1234/v1 --tim
|
|
|
51
82
|
|
|
52
83
|
Timeouts are stored per local provider in milliseconds; pass `--no-timeout` or `--timeout false` to disable the provider timeout.
|
|
53
84
|
|
|
54
|
-
|
|
85
|
+
Then create a local agent:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
letta --backend local --new-agent --model anthropic/claude-sonnet-4-6
|
|
89
|
+
```
|
|
55
90
|
|
|
56
|
-
|
|
57
|
-
Letta Code is built around long-lived agents that persist across sessions and improve with use. Rather than working in independent sessions, each session is tied to a persisted agent that learns.
|
|
91
|
+
Local backend state is stored by default in:
|
|
58
92
|
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
- Context = messages in the current session + `AGENTS.md`
|
|
63
|
-
- Relationship: Every conversation is like meeting a new contractor
|
|
93
|
+
```text
|
|
94
|
+
~/.letta/lc-local-backend
|
|
95
|
+
```
|
|
64
96
|
|
|
65
|
-
|
|
66
|
-
- Same agent across sessions
|
|
67
|
-
- Persistent memory and learning over time
|
|
68
|
-
- `/clear` starts a new conversation (aka "thread" or "session"), but memory persists
|
|
69
|
-
- Relationship: Like having a coworker or mentee that learns and remembers
|
|
97
|
+
You can override this location for isolated experiments:
|
|
70
98
|
|
|
71
|
-
## Agent Memory & Learning
|
|
72
|
-
If you’re using Letta Code for the first time, you will likely want to run the `/init` command to initialize the agent’s memory system:
|
|
73
99
|
```bash
|
|
74
|
-
|
|
100
|
+
export LETTA_LOCAL_BACKEND_DIR="$PWD/.letta-local"
|
|
101
|
+
letta --backend local --new-agent
|
|
75
102
|
```
|
|
76
103
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
104
|
+
Local agents do not appear in the Constellation, but their memory is still a normal git repository under `~/.letta/lc-local-backend/memfs/<agent-id>/memory`.
|
|
105
|
+
|
|
106
|
+
## 🌌 Constellation
|
|
107
|
+
|
|
108
|
+
Agents created with Constellation can be accessed from any machine: your laptop, [GitHub Actions](https://github.com/letta-ai/letta-code-action), a sandbox, remote VM, or a Mac Mini. You can also chat with agents through [chat.letta.com](https://chat.letta.com/) or through the desktop app.
|
|
109
|
+
|
|
110
|
+
```mermaid
|
|
111
|
+
graph TD
|
|
112
|
+
Constellation["🌌 Constellation"]
|
|
113
|
+
Constellation --> A["💻 Your Laptop"]
|
|
114
|
+
Constellation --> B["☁️ Cloud VM"]
|
|
115
|
+
Constellation --> C["🖥️ Mac Mini"]
|
|
116
|
+
Constellation --> D["📦 Sandbox"]
|
|
80
117
|
```
|
|
81
|
-
|
|
118
|
+
|
|
119
|
+
### Remote environments
|
|
120
|
+
|
|
121
|
+
If you're interacting with an agent from desktop or chat.letta.com, you can set agents to run on any available environment. Any machine can be made into an available environment by running:
|
|
122
|
+
|
|
82
123
|
```bash
|
|
83
|
-
|
|
124
|
+
letta server
|
|
125
|
+
letta server --env-name "work-laptop"
|
|
84
126
|
```
|
|
85
127
|
|
|
86
|
-
|
|
128
|
+
See our guides for using [Railway](https://docs.letta.com/letta-code/remote#railway), [DigitalOcean](https://docs.letta.com/letta-code/remote#digitalocean), and [Fly.io](https://docs.letta.com/letta-code/remote#flyio) as remote environments.
|
|
129
|
+
|
|
130
|
+
## Research
|
|
131
|
+
|
|
132
|
+
Letta Code is developed by the creators of [MemGPT](https://arxiv.org/abs/2310.08560) and [sleep-time compute](https://arxiv.org/abs/2504.13171) (now called "dreaming"), and driven by our [research](https://www.letta.com/research) in AI memory and continual learning.
|
|
133
|
+
|
|
134
|
+
## Other
|
|
87
135
|
|
|
88
136
|
Community maintained packages are available for Arch Linux users on the [AUR](https://aur.archlinux.org/packages/letta-code):
|
|
137
|
+
|
|
89
138
|
```bash
|
|
90
139
|
yay -S letta-code # release
|
|
91
140
|
yay -S letta-code-git # nightly
|
|
92
141
|
```
|
|
93
142
|
|
|
143
|
+
Nix users can run or install Letta Code through the repository flake:
|
|
144
|
+
```bash
|
|
145
|
+
nix run github:letta-ai/letta-code
|
|
146
|
+
nix profile install github:letta-ai/letta-code
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
See [docs/nix.md](docs/nix.md) for Home Manager and NixOS service examples.
|
|
150
|
+
|
|
94
151
|
---
|
|
95
152
|
|
|
96
153
|
Made with 💜 in San Francisco
|
package/dist/types/protocol.d.ts
CHANGED
|
@@ -255,7 +255,7 @@ export type QueueItemSource = "user" | "task_notification" | "cron" | "channel"
|
|
|
255
255
|
* - message: User or system text to send to the agent
|
|
256
256
|
* - task_notification: Background task completed notification
|
|
257
257
|
* - approval_result: Tool approval/denial result
|
|
258
|
-
* - overlay_action:
|
|
258
|
+
* - overlay_action: AskUserQuestion or other overlay action
|
|
259
259
|
*/
|
|
260
260
|
export type QueueItemKind = "message" | "task_notification" | "cron_prompt" | "approval_result" | "overlay_action";
|
|
261
261
|
/**
|
|
@@ -320,7 +320,7 @@ export interface QueueBatchDequeuedEvent extends MessageEnvelope {
|
|
|
320
320
|
* Why the queue cannot dequeue right now.
|
|
321
321
|
* - streaming: Agent turn is actively running/streaming (request, response, or local tool execution)
|
|
322
322
|
* - pending_approvals: Waiting for HITL approval decisions
|
|
323
|
-
* - overlay_open:
|
|
323
|
+
* - overlay_open: AskUserQuestion or other overlay is active
|
|
324
324
|
* - command_running: Slash command is executing
|
|
325
325
|
* - interrupt_in_progress: User interrupt (Esc) is being processed
|
|
326
326
|
* - runtime_busy: Generic busy state (e.g., listen-client turn in flight)
|
package/docs/nix.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Nix and NixOS installation
|
|
2
|
+
|
|
3
|
+
Letta Code ships a flake for Nix users who want a native install path instead of a global npm install.
|
|
4
|
+
|
|
5
|
+
## Try once
|
|
6
|
+
|
|
7
|
+
From a machine with flakes enabled:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
nix run github:letta-ai/letta-code
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To run from a local checkout:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
nix run .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Install into a profile
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
nix profile install github:letta-ai/letta-code
|
|
23
|
+
letta
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Home Manager
|
|
27
|
+
|
|
28
|
+
Add Letta Code as a flake input and enable the module:
|
|
29
|
+
|
|
30
|
+
```nix
|
|
31
|
+
{
|
|
32
|
+
inputs.letta-code.url = "github:letta-ai/letta-code";
|
|
33
|
+
|
|
34
|
+
outputs = { nixpkgs, home-manager, letta-code, ... }: {
|
|
35
|
+
homeConfigurations.example = home-manager.lib.homeManagerConfiguration {
|
|
36
|
+
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
|
37
|
+
modules = [
|
|
38
|
+
letta-code.homeManagerModules.default
|
|
39
|
+
{
|
|
40
|
+
programs.letta-code.enable = true;
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## NixOS service
|
|
49
|
+
|
|
50
|
+
For an always-on listener or channel host, enable the NixOS module and provide secrets through a root-readable environment file:
|
|
51
|
+
|
|
52
|
+
```nix
|
|
53
|
+
{
|
|
54
|
+
inputs.letta-code.url = "github:letta-ai/letta-code";
|
|
55
|
+
|
|
56
|
+
outputs = { nixpkgs, letta-code, ... }: {
|
|
57
|
+
nixosConfigurations.agent-host = nixpkgs.lib.nixosSystem {
|
|
58
|
+
system = "x86_64-linux";
|
|
59
|
+
modules = [
|
|
60
|
+
letta-code.nixosModules.default
|
|
61
|
+
{
|
|
62
|
+
services.letta-code = {
|
|
63
|
+
enable = true;
|
|
64
|
+
environmentFile = "/run/secrets/letta-code.env";
|
|
65
|
+
extraArgs = [ "listen" ];
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The environment file can contain values such as:
|
|
75
|
+
|
|
76
|
+
```dotenv
|
|
77
|
+
LETTA_API_KEY=...
|
|
78
|
+
ANTHROPIC_API_KEY=...
|
|
79
|
+
OPENAI_API_KEY=...
|
|
80
|
+
SLACK_BOT_TOKEN=...
|
|
81
|
+
SLACK_SIGNING_SECRET=...
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Use your normal NixOS secret manager, such as sops-nix or agenix, to materialize that file.
|
|
85
|
+
|
|
86
|
+
## What this provides
|
|
87
|
+
|
|
88
|
+
The flake exposes:
|
|
89
|
+
|
|
90
|
+
- `packages.<system>.default` / `packages.<system>.letta-code`
|
|
91
|
+
- `apps.<system>.default` / `apps.<system>.letta`
|
|
92
|
+
- `homeManagerModules.default` and the compatibility alias `homeModules.default`
|
|
93
|
+
- `nixosModules.default`
|
|
94
|
+
|
|
95
|
+
The package builds the Letta Code CLI from this repository with Bun. Dependency resolution is driven by the checked-in `bun.lock`; the generated `bun.nix` file lets the flake prefetch those Bun dependencies reproducibly for offline Nix builds. The resulting `letta` binary is wrapped with common runtime tools, and agent configuration and credentials stay in the normal Letta Code locations.
|
|
96
|
+
|
|
97
|
+
When `bun.lock` changes, regenerate the Nix dependency expression before opening the PR:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
bunx bun2nix -o bun.nix
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Follow-up packaging work
|
|
104
|
+
|
|
105
|
+
This in-repository flake is the fastest path for Nix users to try and deploy Letta Code. A future nixpkgs or Home Manager upstream package should reuse the same shape, but may need additional hardening around native Node dependencies such as `node-pty`, `sharp`, and optional ripgrep binaries.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Discord channel policy consolidation plan
|
|
2
|
+
|
|
3
|
+
This branch consolidates the overlapping Discord channel work from PR #2045 and PR #2306.
|
|
4
|
+
|
|
5
|
+
## Direction
|
|
6
|
+
|
|
7
|
+
- Use PR #2306 as the architectural base for per-channel Discord behavior.
|
|
8
|
+
- Keep the per-channel `allowed_channels` mode map instead of the account-level `channelPolicy` field from PR #2045.
|
|
9
|
+
- Keep `thread_policy_by_channel`, delivery-time `allowed_channels` enforcement, `parentChannelId`, route reconciliation, and route cleanup gated by `remove_stale_routes`.
|
|
10
|
+
- Preserve legacy-safe defaults unless a breaking behavior change is made deliberately in a later PR.
|
|
11
|
+
- Port the useful orthogonal pieces from PR #2045: Discord audio transcription and setup-flow coverage for the new options.
|
|
12
|
+
|
|
13
|
+
## Keep from PR #2306
|
|
14
|
+
|
|
15
|
+
- `allowed_channels` as either the legacy `string[]` allowlist or a per-channel mode map of `open` / `mention-only`.
|
|
16
|
+
- `thread_policy_by_channel` for per-channel mention-thread behavior.
|
|
17
|
+
- Delivery-time route gating using `parentChannelId` so stale routes cannot bypass current channel policy.
|
|
18
|
+
- `letta channels route reconcile --channel discord` with `--apply` guarded by `remove_stale_routes`.
|
|
19
|
+
- Typing indicators for Discord while an agent response is in flight.
|
|
20
|
+
- `acknowledge_message_reaction` as an explicit opt-in/out knob.
|
|
21
|
+
- Snake-case persisted config migration for newly added account fields.
|
|
22
|
+
|
|
23
|
+
## Port from PR #2045
|
|
24
|
+
|
|
25
|
+
- Discord `transcribe_voice` support for inbound audio attachments.
|
|
26
|
+
- Discord setup prompts for guild channel mode, mention thread behavior, debounce, reaction acknowledgments, and audio transcription.
|
|
27
|
+
- Mention-preserving debounce semantics so an explicit mention in a buffered burst is not lost.
|
|
28
|
+
|
|
29
|
+
## Fix before opening the PR
|
|
30
|
+
|
|
31
|
+
- Keep `autoThreadOnMention` defaulting to `false`; Discord thread creation is opt-in.
|
|
32
|
+
- Keep `inboundDebounceMs` defaulting to `0` / disabled; open-channel debounce remains opt-in.
|
|
33
|
+
- Do not overload `isMention` for open-channel routing; carry `isOpenChannel` separately.
|
|
34
|
+
- Remove the unrelated Discord MessageChannel tool-result format change.
|
|
35
|
+
- Add/update targeted tests for defaults, routing semantics, transcription, setup config, and websocket/config round trips.
|