@letta-ai/letta-code 0.34.16 → 0.34.18

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 (68) hide show
  1. package/README.md +14 -5
  2. package/dist/agent-presets.js +5 -1
  3. package/dist/agent-presets.js.map +2 -2
  4. package/dist/mcp-client.js +2 -2
  5. package/dist/mcp-client.js.map +1 -1
  6. package/dist/mcp-oauth.js +30 -28
  7. package/dist/mcp-oauth.js.map +4 -4
  8. package/dist/types/agent/client-skills.d.ts.map +1 -1
  9. package/dist/types/agent/message.d.ts.map +1 -1
  10. package/dist/types/agent/model-handles.d.ts.map +1 -1
  11. package/dist/types/agent/preloaded-skills.d.ts +4 -0
  12. package/dist/types/agent/preloaded-skills.d.ts.map +1 -0
  13. package/dist/types/agent/skills.d.ts.map +1 -1
  14. package/dist/types/agent/subagents/child-send-tracking.d.ts.map +1 -1
  15. package/dist/types/agent/subagents/index.d.ts.map +1 -1
  16. package/dist/types/agent/subagents/manager.d.ts.map +1 -1
  17. package/dist/types/agent/subagents/remote-turn-wait.d.ts.map +1 -1
  18. package/dist/types/agent/subagents/subagent-stream.d.ts.map +1 -1
  19. package/dist/types/agent/turn-recovery-policy.d.ts +1 -1
  20. package/dist/types/agent/turn-recovery-policy.d.ts.map +1 -1
  21. package/dist/types/auth/oauth.d.ts +8 -1
  22. package/dist/types/auth/oauth.d.ts.map +1 -1
  23. package/dist/types/backend/api/conversation-enqueue.d.ts +4 -1
  24. package/dist/types/backend/api/conversation-enqueue.d.ts.map +1 -1
  25. package/dist/types/backend/dev/fake-headless-backend.d.ts +9 -2
  26. package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
  27. package/dist/types/backend/local/compaction.d.ts +5 -0
  28. package/dist/types/backend/local/compaction.d.ts.map +1 -1
  29. package/dist/types/backend/local/local-backend.d.ts.map +1 -1
  30. package/dist/types/headless-listener-launch.d.ts +5 -3
  31. package/dist/types/headless-listener-launch.d.ts.map +1 -1
  32. package/dist/types/headless-super-run-wait.d.ts +1 -1
  33. package/dist/types/headless-super-run-wait.d.ts.map +1 -1
  34. package/dist/types/mcp-oauth-callback.d.ts +5 -1
  35. package/dist/types/mcp-oauth-callback.d.ts.map +1 -1
  36. package/dist/types/mcp-oauth.d.ts.map +1 -1
  37. package/dist/types/tools/impl/code-mode.d.ts +23 -0
  38. package/dist/types/tools/impl/code-mode.d.ts.map +1 -0
  39. package/dist/types/tools/impl/process_manager.d.ts +1 -0
  40. package/dist/types/tools/impl/process_manager.d.ts.map +1 -1
  41. package/dist/types/tools/impl/remote-external-coding-agent.d.ts +1 -0
  42. package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
  43. package/dist/types/tools/impl/task-stop.d.ts.map +1 -1
  44. package/dist/types/tools/impl/workflow.d.ts +5 -0
  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/sdk-spawner.d.ts.map +1 -1
  54. package/dist/types/tools/workflow/types.d.ts +2 -0
  55. package/dist/types/tools/workflow/types.d.ts.map +1 -1
  56. package/dist/types/tools/workflow/workflow-engine.d.ts +2 -0
  57. package/dist/types/tools/workflow/workflow-engine.d.ts.map +1 -1
  58. package/letta.js +13825 -13502
  59. package/npm-shrinkwrap.json +86 -86
  60. package/package.json +2 -2
  61. package/scripts/source-file-size-baseline.json +3 -3
  62. package/skills/creating-skills/SKILL.md +14 -13
  63. package/skills/maintaining-core-memory/SKILL.md +101 -0
  64. package/skills/maintaining-deferred-memory/SKILL.md +84 -0
  65. package/skills/music-generation/LICENSE +21 -0
  66. package/skills/music-generation/SKILL.md +164 -0
  67. package/skills/speech-generation/SKILL.md +15 -36
  68. package/skills/workflow-authoring/SKILL.md +3 -1
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: maintaining-deferred-memory
3
+ description: Maintains deferred memory, which stores accumulated knowledge, analysis, and observations made by the agent over time. Use when saving knowledge (e.g. about a person, project, repository, system, or event). Do NOT use for managing skills, prompts, or for saving information that is already automatically stored in the message history.
4
+ ---
5
+
6
+ Deferred memory contains the agent's knowledge. Use deferred memory for understanding of a subject that matters only when that subject comes up. If the agent needs it on most turns, it is core memory: use the `maintaining-core-memory` skill. If it is a procedure with a trigger, use the `creating-skills` skill.
7
+
8
+ Deferred memory should NOT be used to store:
9
+ - Information that can be accessed by querying the message history (recall memory). For example, logs of specific interactions can simply be looked up in past messages. Reserve deferred memory to store knowledge that is actually *derived* from experience, or to organize knowledge in a way that optimizes recalling the right information at the right time through progressive disclosure.
10
+ - Justifications or reasons for updating memory. These belong in the git commit history of MemFS.
11
+
12
+ ## Check the limits first
13
+
14
+ Read `$MEMORY_DIR/.memfs.config.json` if it exists. The memory repository's pre-commit hook enforces it:
15
+
16
+ - `maxDepth` limits how many directories can sit between the memory root and a file (default 2). `persona.md` is depth 0, `projects/MEMORY.md` is depth 1, and `projects/acme/notes.md` is depth 2. `skills/` is exempt.
17
+ - `maxFileCharacters` caps each memory file, frontmatter included (default 20,000 characters). `fileCharacterLimits` overrides it per glob; the first match wins and `null` removes the cap.
18
+ - `readOnlyFiles` lists globs whose files cannot change. Do not edit them.
19
+
20
+ When the config file is absent, the defaults apply. When content does not fit, split it into more files or flatten the structure; change the config only when the user asks.
21
+
22
+ ## Layout
23
+
24
+ ```text
25
+ $MEMORY_DIR/
26
+ ├── MEMORY.md # root index (core memory)
27
+ └── projects/
28
+ ├── MEMORY.md # index for projects/
29
+ ├── acme.md
30
+ └── acme/
31
+ ├── MEMORY.md # index for projects/acme/
32
+ └── incidents.md
33
+ ```
34
+ - The top-level `MEMORY.md` is always in context, so it must tell the agent what each subdirectory contains and when to open it. Without that entry the directory is never read.
35
+ - `skills/` is reserved for skills and is never deferred memory.
36
+ - A directory is memory only when it has its own `MEMORY.md`. The agent will not discover a directory without one, and neither will the files in it.
37
+ - Every `MEMORY.md` has no frontmatter.
38
+ - Every other Markdown file starts with frontmatter containing exactly two fields:
39
+
40
+ ```markdown
41
+ ---
42
+ name: acme
43
+ description: How the Acme integration works, why it fails, and what to do about it.
44
+ ---
45
+ ```
46
+
47
+ - `description` says what the file is about. The agent sees it when it lists the directory, so make it specific enough to decide whether to open the file.
48
+ - Name files and directories after their subject, not after a date or session. Group related subjects under one directory instead of creating many top-level directories.
49
+
50
+ ## Write the indexes
51
+
52
+ Discovery runs through the `MEMORY.md` chain, one level at a time:
53
+
54
+ - The system prompt lists each top-level memory directory only by path. Add a line to root `MEMORY.md` saying when to open the directory, in the words a future request would use. When a deeper file's topic would not be guessable from that line, name the file there too.
55
+ - When the agent opens a directory, it sees that directory's `MEMORY.md`, then each file's `description` and each subdirectory's index summary (the first prose paragraph of its `MEMORY.md`). Start every `MEMORY.md` with that summary paragraph.
56
+ - A directory listing shows at most 10 entries, most recently edited first, so stable files fall out of it. Link every file that matters from its `MEMORY.md` rather than relying on the listing.
57
+ - Use relative Markdown links from the memory root, such as `[Acme](projects/acme.md)`.
58
+
59
+ After adding or moving a file, trace the path a future request would take from root `MEMORY.md` to the file. If any step depends on knowing the file already exists, fix the index.
60
+
61
+ ## Design for progressive disclosure
62
+
63
+ Each level should give the agent enough to decide whether to go deeper, and nothing it would have to read past to decide.
64
+
65
+ - Put frequently needed material shallow and rarely needed detail deeper. Keep related material in one directory so it loads together.
66
+ - A small topic, where most of the content is useful whenever the subject comes up, belongs entirely in its directory's `MEMORY.md`. Splitting it adds reads without saving context.
67
+ - For a large topic, `MEMORY.md` holds only what the agent needs every time it opens the directory, plus a map: what each deeper file or subdirectory covers and when it is worth opening. The map should also tell the agent when it can stop.
68
+ - A `description` states what the file is about, not when to use it; when-to-open belongs in the parent's link. If you can write a "use when the user wants to…" trigger, the content is a procedure and belongs in a skill.
69
+ - Make each statement stand alone. Name the subject instead of writing "it" or "the repo", because the agent may read only part of a file.
70
+ - Aim for fewer than 10 entries per directory so the listing stays complete. At the `maxDepth` limit, use clearly scoped sibling files linked from `MEMORY.md` rather than nesting further.
71
+
72
+ ## Write analysis, not logs
73
+
74
+ Recall already returns what happened. A deferred memory file is worth keeping only when it holds what recall cannot: the agent's own synthesis of a subject, built across many events and refined as understanding improves.
75
+
76
+ - Before writing, ask whether searching message history would give a future agent the same thing. If it would, do not write the file.
77
+ - Write the current understanding: how the subject works, the patterns across events, why things failed or succeeded, what to do about it, and the open questions.
78
+ - Revise the file in place when new evidence arrives. Fold the new event into the analysis; never append a dated entry, a quote, or an incident narrative.
79
+ - When the file you are updating is already a log, convert it: write the analysis the entries support and delete the entries. Keeping them under an "incident history" heading leaves the log in place; git and recall already hold it.
80
+ - When a raw event matters, point to it with terms that will find it in recall rather than copying it.
81
+ - Keep one home per subject. Update the existing file instead of adding a near-duplicate, and replace stale conclusions where they live.
82
+ - Leave out content the agent can cheaply rederive from the source of truth: file contents, command lists, and current status. Link to the owning source instead.
83
+ - Never store secrets. Reference them by name, such as `$SECRET_NAME`.
84
+
@@ -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`:
@@ -80,7 +80,9 @@ Cloud decisions service.
80
80
  `phase` (progress group — use this inside concurrent stages), `schema`,
81
81
  `json`, `model`, `effort` (`'low'` for mechanical stages, higher for the
82
82
  hardest verify/judge stages), `allowedTools`, `systemPrompt` (extra system
83
- prompt for this subagent), `timeoutMs` (default 10 minutes), `maxToolCalls`
83
+ prompt for this subagent), `skills` (skill names whose full content is
84
+ loaded into the subagent's prompt; workers otherwise have no skills),
85
+ `timeoutMs` (default 10 minutes), `maxToolCalls`
84
86
  (positive safe integer; default 1000 unique tool calls for this subagent),
85
87
  `conversationId` (resume a worker — see "Diagnosing a run").
86
88
  - `pipeline(items, stage1, stage2, ...)` → run each item through all stages