@letta-ai/letta-code 0.34.15 → 0.34.17

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.
Files changed (75) hide show
  1. package/README.md +2 -5
  2. package/dist/app-server-client.cjs +22 -2
  3. package/dist/app-server-client.cjs.map +4 -4
  4. package/dist/app-server-client.js +22 -2
  5. package/dist/app-server-client.js.map +4 -4
  6. package/dist/mcp-client.js +2 -2
  7. package/dist/mcp-client.js.map +1 -1
  8. package/dist/mcp-oauth.js +30 -28
  9. package/dist/mcp-oauth.js.map +4 -4
  10. package/dist/types/agent/message.d.ts.map +1 -1
  11. package/dist/types/agent/model-handles.d.ts.map +1 -1
  12. package/dist/types/agent/skills.d.ts.map +1 -1
  13. package/dist/types/agent/subagents/manager.d.ts.map +1 -1
  14. package/dist/types/agent/turn-recovery-policy.d.ts +2 -1
  15. package/dist/types/agent/turn-recovery-policy.d.ts.map +1 -1
  16. package/dist/types/app-server-client.d.ts +14 -8
  17. package/dist/types/app-server-client.d.ts.map +1 -1
  18. package/dist/types/backend/api/environments.d.ts +2 -0
  19. package/dist/types/backend/api/environments.d.ts.map +1 -1
  20. package/dist/types/backend/dev/fake-headless-backend.d.ts +9 -2
  21. package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
  22. package/dist/types/backend/dev/local-provider-errors.d.ts.map +1 -1
  23. package/dist/types/backend/local/compaction.d.ts +5 -0
  24. package/dist/types/backend/local/compaction.d.ts.map +1 -1
  25. package/dist/types/backend/local/local-backend.d.ts.map +1 -1
  26. package/dist/types/mcp-oauth-callback.d.ts +5 -1
  27. package/dist/types/mcp-oauth-callback.d.ts.map +1 -1
  28. package/dist/types/mcp-oauth.d.ts.map +1 -1
  29. package/dist/types/reminders/engine.d.ts +7 -0
  30. package/dist/types/reminders/engine.d.ts.map +1 -1
  31. package/dist/types/tools/impl/code-mode.d.ts +23 -0
  32. package/dist/types/tools/impl/code-mode.d.ts.map +1 -0
  33. package/dist/types/tools/impl/external-coding-agent-task.d.ts +2 -0
  34. package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
  35. package/dist/types/tools/impl/external-coding-agent.d.ts +13 -1
  36. package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
  37. package/dist/types/tools/impl/process_manager.d.ts +1 -0
  38. package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
  39. package/dist/types/tools/impl/remote-external-coding-agent.d.ts +37 -1
  40. package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
  41. package/dist/types/tools/impl/send-agent-message.d.ts +2 -0
  42. package/dist/types/tools/impl/send-agent-message.d.ts.map +1 -1
  43. package/dist/types/tools/impl/task-stop.d.ts +4 -1
  44. package/dist/types/tools/impl/task-stop.d.ts.map +1 -1
  45. package/dist/types/tools/impl/workflow.d.ts.map +1 -1
  46. package/dist/types/tools/manager.d.ts.map +1 -1
  47. package/dist/types/tools/script-tool-scope.d.ts +19 -0
  48. package/dist/types/tools/script-tool-scope.d.ts.map +1 -0
  49. package/dist/types/tools/tool-definitions.d.ts +1 -0
  50. package/dist/types/tools/tool-definitions.d.ts.map +1 -1
  51. package/dist/types/tools/toolset-catalog.d.ts +1 -1
  52. package/dist/types/tools/toolset-catalog.d.ts.map +1 -1
  53. package/dist/types/tools/workflow/workflow-engine.d.ts +2 -0
  54. package/dist/types/tools/workflow/workflow-engine.d.ts.map +1 -1
  55. package/dist/types/types/app-server-info.d.ts +2 -0
  56. package/dist/types/types/app-server-info.d.ts.map +1 -1
  57. package/dist/types/types/app-server-protocol.d.ts +4 -0
  58. package/dist/types/types/app-server-protocol.d.ts.map +1 -1
  59. package/dist/types/types/protocol_v2.d.ts +1 -0
  60. package/dist/types/types/protocol_v2.d.ts.map +1 -1
  61. package/dist/types/types/subagent-protocol.d.ts +34 -0
  62. package/dist/types/types/subagent-protocol.d.ts.map +1 -1
  63. package/dist/types/websocket/listener/protocol-outbound.d.ts.map +1 -1
  64. package/dist/types/websocket/listener/queue.d.ts.map +1 -1
  65. package/dist/types/websocket/listener/types.d.ts +4 -3
  66. package/dist/types/websocket/listener/types.d.ts.map +1 -1
  67. package/letta.js +14118 -13255
  68. package/npm-shrinkwrap.json +2 -2
  69. package/package.json +1 -1
  70. package/scripts/source-file-size-baseline.json +7 -5
  71. package/skills/creating-skills/SKILL.md +14 -13
  72. package/skills/music-generation/LICENSE +21 -0
  73. package/skills/music-generation/SKILL.md +164 -0
  74. package/skills/speech-generation/SKILL.md +15 -36
  75. package/skills/working-across-computers/SKILL.md +4 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.34.15",
3
+ "version": "0.34.17",
4
4
  "lockfileVersion": 3,
5
5
  "packages": {
6
6
  "node_modules/@alcalzone/ansi-tokenize": {
@@ -5452,7 +5452,7 @@
5452
5452
  },
5453
5453
  "": {
5454
5454
  "name": "@letta-ai/letta-code",
5455
- "version": "0.34.15",
5455
+ "version": "0.34.17",
5456
5456
  "dependencies": {
5457
5457
  "@earendil-works/pi-ai": "^0.99.1",
5458
5458
  "@janhapke/sharp-electron": "0.35.3-electron.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letta-ai/letta-code",
3
- "version": "0.34.15",
3
+ "version": "0.34.17",
4
4
  "lettaStartupLogProtocol": 1,
5
5
  "description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
6
6
  "type": "module",
@@ -9,7 +9,7 @@
9
9
  "src/cli/app/use-approval-flow.ts": 1071,
10
10
  "src/cli/app/use-configuration-handlers.ts": 1417,
11
11
  "src/cli/app/use-conversation-loop.ts": 2860,
12
- "src/cli/app/use-submit-handler.ts": 3801,
12
+ "src/cli/app/use-submit-handler.ts": 3797,
13
13
  "src/cli/components/AgentSelector.tsx": 1104,
14
14
  "src/cli/components/InputRich.tsx": 2116,
15
15
  "src/cli/components/ModelSelector.tsx": 1259,
@@ -19,7 +19,7 @@
19
19
  "src/cli/mods/local-mod-loader.test.ts": 1043,
20
20
  "src/cli/reflection-transcript.test.ts": 1084,
21
21
  "src/cli/subcommands/skills.ts": 1264,
22
- "src/headless.ts": 4778,
22
+ "src/headless.ts": 4771,
23
23
  "src/hooks/integration.test.ts": 1147,
24
24
  "src/index.ts": 2575,
25
25
  "src/mods/learning-harness.ts": 2434,
@@ -33,12 +33,14 @@
33
33
  "src/providers/chatgpt-usage-service.ts": 1112,
34
34
  "src/settings-manager.test.ts": 1635,
35
35
  "src/settings-manager.ts": 2092,
36
- "src/tools/manager.ts": 2609,
36
+ "src/tools/manager.ts": 2606,
37
37
  "src/tools/tool-execution-context.test.ts": 1092,
38
- "src/types/protocol_v2.ts": 2531,
38
+ "src/types/protocol_v2.ts": 2532,
39
+ "src/websocket/listener/message-router.ts": 1005,
39
40
  "src/websocket/listen-client-concurrency.test.ts": 2557,
40
41
  "src/websocket/listen-client-protocol.test.ts": 5664,
41
42
  "src/websocket/listener/commands/memory.ts": 1114,
42
43
  "src/websocket/listener/file-commands.ts": 1045,
43
- "src/websocket/listener/protocol-inbound.ts": 2055
44
+ "src/websocket/listener/protocol-inbound.ts": 2054,
45
+ "src/websocket/listener/protocol-outbound.ts": 1001
44
46
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: creating-skills
3
- description: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Letta Code's capabilities with specialized knowledge, workflows, or tool integrations.
3
+ description: Guide for creating effective skills. Use when creating a new skill or updating an existing one that extends Letta Code's capabilities with specialized knowledge, workflows, or tool integrations, whether a user asks for it or a reusable workflow is worth capturing.
4
4
  ---
5
5
 
6
6
  # Creating Skills
@@ -206,7 +206,7 @@ Skill creation involves these steps:
206
206
  2. Plan reusable skill contents (scripts, references, assets)
207
207
  3. Initialize the skill (run init-skill.ts)
208
208
  4. Edit the skill (implement resources and write SKILL.md)
209
- 5. Package the skill (run package-skill.ts)
209
+ 5. Package the skill if it will be distributed (run package-skill.ts)
210
210
  6. Iterate based on real usage
211
211
 
212
212
  Follow these steps in order, skipping only if there is a clear reason why they are not applicable.
@@ -215,16 +215,15 @@ Follow these steps in order, skipping only if there is a clear reason why they a
215
215
 
216
216
  Skip this step only when the skill's usage patterns are already clearly understood. It remains valuable even when working with an existing skill.
217
217
 
218
- To create an effective skill, clearly understand concrete examples of how the skill will be used. This understanding can come from either direct user examples or generated examples that are validated with user feedback.
218
+ To create an effective skill, clearly understand concrete examples of how the skill will be used. Draw them from the material at hand first: the conversation or transcripts that motivated the skill, the commands and tool calls that worked, and the requests that would trigger it.
219
219
 
220
- For example, when building an `editing-images` skill, relevant questions include:
220
+ For example, when building an `editing-images` skill, establish:
221
221
 
222
- - "What functionality should the editing-images skill support? Editing, rotating, anything else?"
223
- - "Can you give some examples of how this skill would be used?"
224
- - "I can imagine users asking for things like 'Remove the red-eye from this image' or 'Rotate this image'. Are there other ways you imagine this skill being used?"
225
- - "What would a user say that should trigger this skill?"
222
+ - What functionality the skill should support: editing, rotating, anything else?
223
+ - What concrete requests it should handle, such as "Remove the red-eye from this image" or "Rotate this image"
224
+ - What a user would say that should trigger the skill
226
225
 
227
- To avoid overwhelming users, avoid asking too many questions in a single message. Start with the most important questions and follow up as needed for better effectiveness.
226
+ If you are working with a user and these remain unclear, ask the most important questions first rather than many at once. If no one is available to ask, such as in a background or automated run, do not wait for answers: scope the skill to what the source material demonstrates and leave out functionality it does not support.
228
227
 
229
228
  Conclude this step when there is a clear sense of the functionality the skill should support.
230
229
 
@@ -265,7 +264,7 @@ Usage:
265
264
  ```bash
266
265
  npx tsx <SKILL_DIR>/scripts/init-skill.ts <skill-name> --path <output-directory>
267
266
  ```
268
- Where `<SKILL_DIR>` is the Skill Directory shown when the skill was loaded (visible in the injection header).
267
+ Where `<SKILL_DIR>` is the Skill Directory shown when the skill was loaded (visible in the injection header). If no Skill Directory is shown, create the skill directory and `SKILL.md` directly instead.
269
268
 
270
269
  The script:
271
270
 
@@ -291,7 +290,7 @@ These files contain established best practices for effective skill design.
291
290
 
292
291
  #### Start with Reusable Skill Contents
293
292
 
294
- To begin implementation, start with the reusable resources identified above: `scripts/`, `references/`, and `assets/` files. Note that this step may require user input. For example, when implementing a `brand-guidelines` skill, the user may need to provide brand assets or templates to store in `assets/`, or documentation to store in `references/`.
293
+ To begin implementation, start with the reusable resources identified above: `scripts/`, `references/`, and `assets/` files. Some resources come from outside the source material. For example, a `brand-guidelines` skill may need brand assets or templates in `assets/`, or documentation in `references/`. Ask the user for them if you are working with one; otherwise include only what is available and leave out resources you cannot supply.
295
294
 
296
295
  Added scripts must be tested by actually running them to ensure there are no bugs and that the output matches what is expected. If there are many similar scripts, only a representative sample needs to be tested to ensure confidence that they all work while balancing time to completion.
297
296
 
@@ -333,7 +332,9 @@ Write instructions for using the skill and its bundled resources.
333
332
 
334
333
  ### Step 5: Packaging a Skill
335
334
 
336
- Once development of the skill is complete, it must be packaged into a distributable .skill file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements:
335
+ Package the skill only when it needs to be distributed as a file, for example when sharing it with a user. Skills maintained in place, such as those under an agent's memory `skills/` directory, are used directly and need no packaging.
336
+
337
+ To package a skill into a distributable .skill file, run the packaging script. The packaging process automatically validates the skill first to ensure it meets all requirements:
337
338
 
338
339
  ```bash
339
340
  npx tsx <SKILL_DIR>/scripts/package-skill.ts <path/to/skill-folder>
@@ -360,7 +361,7 @@ If validation fails, the script will report the errors and exit without creating
360
361
 
361
362
  ### Step 6: Iterate
362
363
 
363
- After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed.
364
+ Improve a skill when real usage shows it falling short, whether through user feedback or sessions where the skill was used. Usage with fresh context of how the skill performed is the best evidence.
364
365
 
365
366
  **Iteration workflow:**
366
367
 
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 ElevenLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: music-generation
3
+ description: Generate music using ElevenLabs Music through Letta. Use when creating instrumental tracks, songs with lyrics, background music, jingles, theme songs, or any AI-generated music composition. Supports prompt-based generation and composition plans for section-by-section control.
4
+ license: MIT
5
+ ---
6
+
7
+ # ElevenLabs Music Generation (via Letta)
8
+
9
+ Generate music from text prompts: instrumental tracks, songs with lyrics, and fine-grained control via composition plans. Examples use `music_v2_5`, the most advanced ElevenLabs music model and the endpoint's default.
10
+
11
+ This skill is adapted from ElevenLabs' `music` skill
12
+ ([elevenlabs/skills](https://github.com/elevenlabs/skills), MIT; see `LICENSE`).
13
+ Instead of calling ElevenLabs with your own key, you call Letta's hosted endpoint
14
+ `POST /v1/audio/music` (or `POST /v1/audio/music/stream`). It forwards the
15
+ request to ElevenLabs with Letta's key and charges the organization's Letta
16
+ credits, so you do not need an ElevenLabs API key. The request and response are
17
+ the same as ElevenLabs "Compose music": a JSON body with the same field names,
18
+ `output_format` as a query parameter, and the audio file as the response body.
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ base_url="${LETTA_BASE_URL%/}"
24
+
25
+ curl -sS -X POST "$base_url/v1/audio/music/stream?output_format=mp3_48000_192" \
26
+ -H "Authorization: Bearer $LETTA_API_KEY" \
27
+ -H "Content-Type: application/json" \
28
+ -d '{"prompt":"A chill lo-fi hip hop beat with jazzy piano chords","music_length_ms":30000,"model_id":"music_v2_5"}' \
29
+ --output output.mp3 \
30
+ --write-out '%{http_code} %{content_type}\n'
31
+ ```
32
+
33
+ A `200` with an `audio/...` content type means `output.mp3` is the song. Any
34
+ other status means `output.mp3` holds a JSON error with a `message` instead;
35
+ read it (see "Error Handling") and do not share the file.
36
+
37
+ Use the runtime-provided `LETTA_BASE_URL` and `LETTA_API_KEY` together. Build
38
+ URLs relative to `${LETTA_BASE_URL%/}` and do not hardcode
39
+ `https://api.letta.com`. If either variable is missing, the user needs to
40
+ authenticate with Letta Cloud; do not ask for an ElevenLabs key.
41
+
42
+ Generation takes a while (roughly 10-30 seconds per minute of music). Prefer
43
+ `/v1/audio/music/stream`: it sends audio as it is generated, so long songs do
44
+ not sit on an idle connection. `/v1/audio/music` takes the same request and
45
+ returns the same file, but may send nothing until the whole song is done, so
46
+ use it only for short songs. Do not set a short client timeout either way.
47
+
48
+ Share the saved file the way your current surface supports: attach or upload it
49
+ to the conversation or channel you are replying in. Keep credit amounts out of
50
+ replies unless the user asks about cost.
51
+
52
+ ## Length
53
+
54
+ - A song is 3 seconds to 10 minutes (600,000 ms).
55
+ - With `prompt`, `music_length_ms` is optional. Leave it out to let the model
56
+ choose a length that suits the prompt.
57
+ - With `composition_plan`, the length is the sum of the chunk or section
58
+ `duration_ms` values; do not also send `music_length_ms`.
59
+ - Credits are charged for the length of the audio actually returned, at
60
+ ElevenLabs' per-minute price. Before generating, the organization needs
61
+ enough credits for the longest song the request allows: `music_length_ms`,
62
+ the plan total, or 10 minutes when a prompt sets no length. Setting
63
+ `music_length_ms` lowers that requirement.
64
+
65
+ ## Models
66
+
67
+ | Model ID | Best For |
68
+ |----------|----------|
69
+ | `music_v2_5` | **Default.** Most advanced: best audio quality and prompt adherence. Chunk-based composition plans. |
70
+ | `music_v2` | Previous generation. Chunk-based composition plans. |
71
+ | `music_v1` | Oldest. Section-based composition plans. Use only when explicitly requested. |
72
+
73
+ ## Prompting
74
+
75
+ Describe the music the way a producer would brief a session:
76
+
77
+ - Genre and mood: "melancholic indie folk", "triumphant orchestral trailer".
78
+ - Instrumentation and vocals: "fingerpicked acoustic guitar, soft female vocals".
79
+ - Tempo and key when they matter: "90 BPM", "D minor".
80
+ - Structure and energy: "starts sparse, builds into a big chorus".
81
+ - Lyrics: put them in the prompt for short songs, or use a composition plan
82
+ to control which lines land in which section.
83
+ - Set `force_instrumental: true` to guarantee no vocals (prompt mode only).
84
+
85
+ ## Composition Plans
86
+
87
+ `music_v2_5` composition plans are an ordered list of `chunks`. Each chunk specifies its own
88
+ `text` (section label, lyrics, inline cues), `duration_ms`, `positive_styles`, `negative_styles`,
89
+ and `context_adherence` (`low`, `medium`, or `high`, default `high`). Up to 30 chunks per plan,
90
+ each 3,000–120,000 ms. Each chunk's `text` supports up to 6,132 characters, with up to 30 lines
91
+ of 200 characters each. Send the plan instead of `prompt` and `music_length_ms`:
92
+
93
+ ```json
94
+ {
95
+ "model_id": "music_v2_5",
96
+ "composition_plan": {
97
+ "chunks": [
98
+ {
99
+ "text": "[Verse]\nWalking down an empty street",
100
+ "duration_ms": 15000,
101
+ "positive_styles": ["pop", "upbeat", "female vocals", "acoustic guitar", "120 BPM", "polished production"],
102
+ "negative_styles": ["dark", "slow"],
103
+ "context_adherence": "high"
104
+ },
105
+ {
106
+ "text": "[Chorus]\nThis is my moment",
107
+ "duration_ms": 15000,
108
+ "positive_styles": ["powerful vocals", "full band"],
109
+ "negative_styles": [],
110
+ "context_adherence": "high"
111
+ }
112
+ ]
113
+ }
114
+ }
115
+ ```
116
+
117
+ - Put broader characteristics (genre, instrumentation, vocal style) in `positive_styles`, not in
118
+ `text`. The first chunk's styles set the overall tone — include 6–7 styles there.
119
+ - Use later chunks' styles for progression: "bass joins in", "building intensity", "drums softening".
120
+ - Inline cues in curly braces add moments inside a chunk: `{guitar solo}`, `{vinyl crackle}`.
121
+ - Lower `context_adherence` lets a chunk depart from its neighbors, for a bridge or a key change.
122
+ - `seed` works with composition plans (not with `prompt`) to make results more repeatable.
123
+
124
+ For `music_v1`, plans use `positive_global_styles`, `negative_global_styles`, and `sections`
125
+ (each with `section_name`, `positive_local_styles`, `negative_local_styles`, `duration_ms`, and
126
+ `lines`), and `respect_sections_durations: false` lets the model adjust section lengths.
127
+
128
+ Inpainting and audio references (`song_id` chunks, `conditioning_ref`, `source_from`) are not
129
+ available through this endpoint and return 400.
130
+
131
+ ## Output Formats
132
+
133
+ Pass `output_format` as a query parameter, not in the body. The default, `auto`,
134
+ gives `mp3_48000_192` for `music_v2` and later (`mp3_44100_128` for `music_v1`).
135
+ Name the file to match the format.
136
+
137
+ | Format | Description |
138
+ |--------|-------------|
139
+ | `mp3_48000_192` | MP3 48kHz 192kbps (what `auto` picks for v2 models) |
140
+ | `mp3_48000_320` | MP3 48kHz 320kbps - highest quality MP3 |
141
+ | `mp3_44100_128` | MP3 44.1kHz 128kbps - smaller files |
142
+ | `pcm_48000` | Raw 16-bit PCM 48kHz, no header - for further processing |
143
+ | `opus_48000_128` | Opus 48kHz 128kbps in Ogg - efficient codec, small files |
144
+
145
+ ## Content Restrictions
146
+
147
+ - Cannot reference specific artists, bands, or copyrighted lyrics. Describe the style instead
148
+ ("1960s British invasion rock" rather than a band name).
149
+ - A rejected prompt returns 400 with ElevenLabs' `bad_prompt` detail, which includes a
150
+ `prompt_suggestion` with alternative phrasing. A rejected plan returns `bad_composition_plan`
151
+ with a `composition_plan_suggestion`. Retry with the suggestion.
152
+
153
+ ## Error Handling
154
+
155
+ Errors return JSON with a `message`:
156
+ - **400 with an ElevenLabs message**: invalid parameters or restricted content (see "Content Restrictions").
157
+ - **400 "Provide prompt or composition_plan."**: send one of them.
158
+ - **402**: the organization does not have enough Letta credits for the longest song the request
159
+ allows (`credits_required`). Setting a shorter `music_length_ms` may help; otherwise tell the user
160
+ and do not retry.
161
+ - **500**: retry once, then report the failure.
162
+
163
+ If the connection drops partway through `/stream`, the file is truncated; only the audio
164
+ received is charged. Retry the request rather than sharing a partial song.
@@ -14,7 +14,8 @@ Instead of calling ElevenLabs with your own key, you call Letta's hosted endpoin
14
14
  `POST /v1/audio/speech`. It forwards the request to ElevenLabs with Letta's key
15
15
  and charges the organization's Letta credits, so you do not need an ElevenLabs
16
16
  API key. The request body uses the same field names as ElevenLabs "Create
17
- speech"; the voice ID goes in the body.
17
+ speech" (the voice ID and `output_format` go in the body), and the response is
18
+ the audio file itself, as with ElevenLabs.
18
19
 
19
20
  ## Quick Start
20
21
 
@@ -25,20 +26,9 @@ curl -sS -X POST "$base_url/v1/audio/speech" \
25
26
  -H "Authorization: Bearer $LETTA_API_KEY" \
26
27
  -H "Content-Type: application/json" \
27
28
  -d '{"text":"Hello, welcome to ElevenLabs!","voice_id":"JBFqnCBsd6RMkjVDRZzb","model_id":"eleven_v4"}' \
28
- > speech-response.json
29
-
30
- python3 - <<'PY'
31
- import base64, json
32
-
33
- with open("speech-response.json") as f:
34
- response = json.load(f)
35
- if "audio_b64" not in response:
36
- raise SystemExit(response.get("message", response))
37
-
38
- with open("output.mp3", "wb") as f:
39
- f.write(base64.b64decode(response["audio_b64"]))
40
- print("saved output.mp3")
41
- PY
29
+ --output output.mp3 \
30
+ --dump-header speech-headers.txt \
31
+ --write-out '%{http_code} %{content_type}\n'
42
32
  ```
43
33
 
44
34
  Use the runtime-provided `LETTA_BASE_URL` and `LETTA_API_KEY` together. Build
@@ -46,9 +36,13 @@ URLs relative to `${LETTA_BASE_URL%/}` and do not hardcode
46
36
  `https://api.letta.com`. If either variable is missing, the user needs to
47
37
  authenticate with Letta Cloud; do not ask for an ElevenLabs key.
48
38
 
39
+ A `200` with an `audio/...` content type means `output.mp3` is the speech. Any
40
+ other status means `output.mp3` holds a JSON error with a `message` instead;
41
+ read it (see "Error Handling") and do not share the file.
42
+
49
43
  Share the saved file the way your current surface supports: attach or upload it
50
- to the conversation or channel you are replying in. Never paste the base64 into
51
- a reply. Keep credit amounts out of replies unless the user asks about cost.
44
+ to the conversation or channel you are replying in. Keep credit amounts out of
45
+ replies unless the user asks about cost.
52
46
 
53
47
  ## Models
54
48
 
@@ -160,8 +154,9 @@ When generating long audio in multiple requests, the audio can have pops, unnatu
160
154
  {"text": "And this continues the story.", "voice_id": "JBFqnCBsd6RMkjVDRZzb", "model_id": "eleven_v4", "previous_text": "This is the first part."}
161
155
  ```
162
156
 
163
- Each response includes `request_id`. Instead of `previous_text`, you can pass up
164
- to three earlier `request_id` values in `previous_request_ids` (and later ones in
157
+ Each response has a `request-id` header (saved by `--dump-header` above, e.g.
158
+ `grep -i '^request-id:' speech-headers.txt`). Instead of `previous_text`, you can
159
+ pass up to three earlier request IDs in `previous_request_ids` (and later ones in
165
160
  `next_request_ids` when regenerating a middle part). Keep the same voice, model,
166
161
  and voice settings for every part, split long text at sentence or paragraph
167
162
  boundaries (each request takes up to 10,000 characters), and concatenate the
@@ -169,7 +164,7 @@ files in order, for example with `ffmpeg -f concat`.
169
164
 
170
165
  ## Output Formats
171
166
 
172
- Pass `output_format` in the body.
167
+ Pass `output_format` in the body, and name the file to match the format.
173
168
 
174
169
  | Format | Description |
175
170
  |--------|-------------|
@@ -187,22 +182,6 @@ Pass `output_format` in the body.
187
182
  | `opus_48000_64` | Opus 48kHz 64kbps - efficient codec, small files |
188
183
  | `wav_44100` | WAV 44.1kHz - uncompressed with headers |
189
184
 
190
- The Letta endpoint returns the whole file at once (as `audio_b64`); it does not stream.
191
-
192
- ## Response
193
-
194
- ```json
195
- {
196
- "model_id": "eleven_v4",
197
- "voice_id": "JBFqnCBsd6RMkjVDRZzb",
198
- "output_format": "mp3_44100_128",
199
- "audio_b64": "<base64>",
200
- "request_id": "Frhov0LQNC3M9HcHKY3t",
201
- "characters": 46,
202
- "billing": { "credits_charged": 4, "transaction_id": "...", "new_credit_balance": "..." }
203
- }
204
- ```
205
-
206
185
  ## Error Handling
207
186
 
208
187
  Errors return JSON with a `message`:
@@ -28,6 +28,10 @@ For remote subagents, set `computer` and pass source paths and destination conve
28
28
 
29
29
  If the user wants to connect a new computer, `letta teleport list` has no suitable target, or the requested local machine is missing or unreachable, read [Connect a computer for remote access](references/connect-a-computer-for-remote-access.md).
30
30
 
31
+ ## Keep active Monitors on their computer
32
+
33
+ A Monitor belongs to the computer where it started. While this conversation has an active Monitor, use a subagent on the requested computer instead of teleporting the parent conversation. If the user explicitly insists on moving the parent conversation, explain that they must stop the Monitor before teleporting the parent conversation; do not retry teleport while the Monitor remains active.
34
+
31
35
  ## Move this conversation
32
36
 
33
37
  **Run the teleport handoff alone as the final tool call.** After success, do not poll or run more source-side tools; the same conversation resumes at the destination automatically. Set the working directory and check required setup there. If teleport fails, stay on the source and resolve the error before retrying. The Cloud sandbox remains available while you work elsewhere.