@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.
- package/README.md +2 -5
- package/dist/app-server-client.cjs +22 -2
- package/dist/app-server-client.cjs.map +4 -4
- package/dist/app-server-client.js +22 -2
- package/dist/app-server-client.js.map +4 -4
- package/dist/mcp-client.js +2 -2
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp-oauth.js +30 -28
- package/dist/mcp-oauth.js.map +4 -4
- package/dist/types/agent/message.d.ts.map +1 -1
- package/dist/types/agent/model-handles.d.ts.map +1 -1
- package/dist/types/agent/skills.d.ts.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/agent/turn-recovery-policy.d.ts +2 -1
- package/dist/types/agent/turn-recovery-policy.d.ts.map +1 -1
- package/dist/types/app-server-client.d.ts +14 -8
- package/dist/types/app-server-client.d.ts.map +1 -1
- package/dist/types/backend/api/environments.d.ts +2 -0
- package/dist/types/backend/api/environments.d.ts.map +1 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts +9 -2
- package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
- package/dist/types/backend/dev/local-provider-errors.d.ts.map +1 -1
- package/dist/types/backend/local/compaction.d.ts +5 -0
- package/dist/types/backend/local/compaction.d.ts.map +1 -1
- package/dist/types/backend/local/local-backend.d.ts.map +1 -1
- package/dist/types/mcp-oauth-callback.d.ts +5 -1
- package/dist/types/mcp-oauth-callback.d.ts.map +1 -1
- package/dist/types/mcp-oauth.d.ts.map +1 -1
- package/dist/types/reminders/engine.d.ts +7 -0
- package/dist/types/reminders/engine.d.ts.map +1 -1
- package/dist/types/tools/impl/code-mode.d.ts +23 -0
- package/dist/types/tools/impl/code-mode.d.ts.map +1 -0
- package/dist/types/tools/impl/external-coding-agent-task.d.ts +2 -0
- package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts +13 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/process_manager.d.ts +1 -0
- package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts +37 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/send-agent-message.d.ts +2 -0
- package/dist/types/tools/impl/send-agent-message.d.ts.map +1 -1
- package/dist/types/tools/impl/task-stop.d.ts +4 -1
- package/dist/types/tools/impl/task-stop.d.ts.map +1 -1
- package/dist/types/tools/impl/workflow.d.ts.map +1 -1
- package/dist/types/tools/manager.d.ts.map +1 -1
- package/dist/types/tools/script-tool-scope.d.ts +19 -0
- package/dist/types/tools/script-tool-scope.d.ts.map +1 -0
- package/dist/types/tools/tool-definitions.d.ts +1 -0
- package/dist/types/tools/tool-definitions.d.ts.map +1 -1
- package/dist/types/tools/toolset-catalog.d.ts +1 -1
- package/dist/types/tools/toolset-catalog.d.ts.map +1 -1
- package/dist/types/tools/workflow/workflow-engine.d.ts +2 -0
- package/dist/types/tools/workflow/workflow-engine.d.ts.map +1 -1
- package/dist/types/types/app-server-info.d.ts +2 -0
- package/dist/types/types/app-server-info.d.ts.map +1 -1
- package/dist/types/types/app-server-protocol.d.ts +4 -0
- package/dist/types/types/app-server-protocol.d.ts.map +1 -1
- package/dist/types/types/protocol_v2.d.ts +1 -0
- package/dist/types/types/protocol_v2.d.ts.map +1 -1
- package/dist/types/types/subagent-protocol.d.ts +34 -0
- package/dist/types/types/subagent-protocol.d.ts.map +1 -1
- package/dist/types/websocket/listener/protocol-outbound.d.ts.map +1 -1
- package/dist/types/websocket/listener/queue.d.ts.map +1 -1
- package/dist/types/websocket/listener/types.d.ts +4 -3
- package/dist/types/websocket/listener/types.d.ts.map +1 -1
- package/letta.js +14118 -13255
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/scripts/source-file-size-baseline.json +7 -5
- package/skills/creating-skills/SKILL.md +14 -13
- package/skills/music-generation/LICENSE +21 -0
- package/skills/music-generation/SKILL.md +164 -0
- package/skills/speech-generation/SKILL.md +15 -36
- package/skills/working-across-computers/SKILL.md +4 -0
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letta-ai/letta-code",
|
|
3
|
-
"version": "0.34.
|
|
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.
|
|
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
|
@@ -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":
|
|
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":
|
|
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":
|
|
36
|
+
"src/tools/manager.ts": 2606,
|
|
37
37
|
"src/tools/tool-execution-context.test.ts": 1092,
|
|
38
|
-
"src/types/protocol_v2.ts":
|
|
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":
|
|
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.
|
|
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.
|
|
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,
|
|
220
|
+
For example, when building an `editing-images` skill, establish:
|
|
221
221
|
|
|
222
|
-
-
|
|
223
|
-
-
|
|
224
|
-
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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"
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.
|
|
51
|
-
|
|
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
|
|
164
|
-
|
|
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.
|