@letta-ai/letta-client 1.11.1 → 1.12.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.
Files changed (53) hide show
  1. package/README.md +337 -228
  2. package/client.d.mts +3 -0
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +3 -0
  5. package/client.d.ts.map +1 -1
  6. package/client.js +3 -0
  7. package/client.js.map +1 -1
  8. package/client.mjs +3 -0
  9. package/client.mjs.map +1 -1
  10. package/internal/detect-platform.d.mts +0 -1
  11. package/internal/detect-platform.d.mts.map +1 -1
  12. package/internal/detect-platform.d.ts +0 -1
  13. package/internal/detect-platform.d.ts.map +1 -1
  14. package/internal/detect-platform.js +0 -5
  15. package/internal/detect-platform.js.map +1 -1
  16. package/internal/detect-platform.mjs +0 -5
  17. package/internal/detect-platform.mjs.map +1 -1
  18. package/package.json +1 -1
  19. package/resources/conversations/conversations.d.mts +32 -0
  20. package/resources/conversations/conversations.d.mts.map +1 -1
  21. package/resources/conversations/conversations.d.ts +32 -0
  22. package/resources/conversations/conversations.d.ts.map +1 -1
  23. package/resources/conversations/conversations.js +5 -2
  24. package/resources/conversations/conversations.js.map +1 -1
  25. package/resources/conversations/conversations.mjs +5 -2
  26. package/resources/conversations/conversations.mjs.map +1 -1
  27. package/resources/environments.d.mts +138 -0
  28. package/resources/environments.d.mts.map +1 -0
  29. package/resources/environments.d.ts +138 -0
  30. package/resources/environments.d.ts.map +1 -0
  31. package/resources/environments.js +28 -0
  32. package/resources/environments.js.map +1 -0
  33. package/resources/environments.mjs +24 -0
  34. package/resources/environments.mjs.map +1 -0
  35. package/resources/index.d.mts +1 -0
  36. package/resources/index.d.mts.map +1 -1
  37. package/resources/index.d.ts +1 -0
  38. package/resources/index.d.ts.map +1 -1
  39. package/resources/index.js +3 -1
  40. package/resources/index.js.map +1 -1
  41. package/resources/index.mjs +1 -0
  42. package/resources/index.mjs.map +1 -1
  43. package/src/client.ts +19 -0
  44. package/src/internal/detect-platform.ts +0 -6
  45. package/src/resources/conversations/conversations.ts +40 -2
  46. package/src/resources/environments.ts +234 -0
  47. package/src/resources/index.ts +8 -0
  48. package/src/version.ts +1 -1
  49. package/version.d.mts +1 -1
  50. package/version.d.ts +1 -1
  51. package/version.js +1 -1
  52. package/version.mjs +1 -1
  53. package/CHANGELOG.md +0 -1085
package/README.md CHANGED
@@ -1,334 +1,443 @@
1
- # Letta TypeScript SDK
1
+ # Letta TypeScript API Library
2
2
 
3
- [![npm shield](https://img.shields.io/npm/v/@letta-ai/letta-client)](https://www.npmjs.com/package/@letta-ai/letta-client)
3
+ [![NPM version](<https://img.shields.io/npm/v/@letta-ai/letta-client.svg?label=npm%20(stable)>)](https://npmjs.org/package/@letta-ai/letta-client) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/@letta-ai/letta-client)
4
4
 
5
- Letta is the platform for building stateful agents: open AI with advanced memory that can learn and self-improve over time.
5
+ This library provides convenient access to the Letta REST API from server-side TypeScript or JavaScript.
6
6
 
7
- - [Letta Code](https://docs.letta.com/letta-code): run agents locally in your terminal
8
- - [Letta API](https://docs.letta.com/quickstart/): build agents into your applications
7
+ The full API of this library can be found in [api.md](api.md).
9
8
 
10
- ## Get started
9
+ It is generated with [Stainless](https://www.stainless.com/).
11
10
 
12
- Install the Letta TypeScript SDK:
11
+ ## Installation
13
12
 
14
- ```bash
13
+ ```sh
15
14
  npm install @letta-ai/letta-client
16
15
  ```
17
16
 
18
- ## Simple Hello World example
19
-
20
- Below is a quick example of creating a stateful agent and sending it a message (requires a [Letta API key](https://app.letta.com), or setting `baseUrl=...` to point at a [Docker server](https://docs.letta.com/guides/docker)).
21
- See the full [quickstart guide](https://docs.letta.com/quickstart) for complete documentation.
22
-
23
- ```typescript
24
- import { Letta } from '@letta-ai/letta-client';
25
-
26
- const client = new Letta({ apiKey: process.env.LETTA_API_KEY });
27
-
28
- const agentState = await client.agents.create({
29
- model: 'openai/gpt-4.1',
30
- embedding: 'openai/text-embedding-3-small',
31
- memory_blocks: [
32
- {
33
- label: 'human',
34
- value: "The human's name is Chad. They like vibe coding.",
35
- },
36
- {
37
- label: 'persona',
38
- value: 'My name is Sam, a helpful assistant.',
39
- },
40
- ],
41
- tools: ['web_search', 'run_code'],
42
- });
17
+ ## Usage
18
+
19
+ The full API of this library can be found in [api.md](api.md).
43
20
 
44
- console.log('Agent created with ID:', agentState.id);
21
+ <!-- prettier-ignore -->
22
+ ```js
23
+ import Letta from '@letta-ai/letta-client';
45
24
 
46
- const response = await client.agents.messages.create(agentState.id, {
47
- input: 'Hey, nice to meet you, my name is Brad.',
25
+ const client = new Letta({
26
+ apiKey: process.env['LETTA_API_KEY'], // This is the default and can be omitted
27
+ environment: 'local', // defaults to 'cloud'
48
28
  });
49
29
 
50
- // the agent will think, then edit its memory using a tool
51
- for (const message of response.messages) {
52
- console.log(message);
53
- }
30
+ const archive = await client.archives.create({ name: 'name' });
54
31
 
55
- // The content of this memory block will be something like
56
- // "The human's name is Brad. They like vibe coding."
57
- // Fetch this block's content with:
58
- const human_block = await client.agents.blocks.retrieve('human', { agent_id: agentState.id });
59
- console.log(human_block.value);
32
+ console.log(archive.id);
60
33
  ```
61
34
 
62
- ## Core concepts in Letta:
35
+ ## Streaming responses
63
36
 
64
- Letta is built on the [MemGPT](https://arxiv.org/abs/2310.08560) research paper, which introduced the concept of the "LLM Operating System" for memory management:
37
+ We provide support for streaming responses using Server Sent Events (SSE).
65
38
 
66
- 1. [**Memory Hierarchy**](https://docs.letta.com/guides/agents/memory): Agents have self-editing memory split between in-context and out-of-context memory
67
- 2. [**Memory Blocks**](https://docs.letta.com/guides/agents/memory-blocks): In-context memory is composed of persistent editable blocks
68
- 3. [**Agentic Context Engineering**](https://docs.letta.com/guides/agents/context-engineering): Agents control their context window using tools to edit, delete, or search memory
69
- 4. [**Perpetual Self-Improving Agents**](https://docs.letta.com/guides/agents/overview): Every agent has a perpetual (infinite) message history
39
+ ```ts
40
+ import Letta from '@letta-ai/letta-client';
41
+
42
+ const client = new Letta();
43
+
44
+ const stream = await client.agents.messages.create('agent-123e4567-e89b-42d3-8456-426614174000', {
45
+ streaming: true,
46
+ });
47
+ for await (const lettaStreamingResponse of stream) {
48
+ console.log(lettaStreamingResponse.messages);
49
+ }
50
+ ```
70
51
 
71
- ## Key Features
52
+ If you need to cancel a stream, you can `break` from the loop
53
+ or call `stream.controller.abort()`.
72
54
 
73
- ### Memory Management ([full guide](https://docs.letta.com/guides/agents/memory-blocks))
55
+ ### Request & Response types
74
56
 
75
- Memory blocks are persistent, editable sections of an agent's context window:
57
+ This library includes TypeScript definitions for all request params and response fields. You may import and use them like so:
76
58
 
77
- ```typescript
78
- // Create agent with memory blocks
79
- const agent = await client.agents.create({
80
- memory_blocks: [
81
- { label: 'persona', value: "I'm a helpful assistant." },
82
- { label: 'human', value: 'User preferences and info.' },
83
- ],
84
- });
59
+ <!-- prettier-ignore -->
60
+ ```ts
61
+ import Letta from '@letta-ai/letta-client';
85
62
 
86
- // Update blocks manually
87
- await client.agents.blocks.update('human', {
88
- agent_id: agent.id,
89
- value: 'Updated user information',
63
+ const client = new Letta({
64
+ apiKey: process.env['LETTA_API_KEY'], // This is the default and can be omitted
65
+ environment: 'local', // defaults to 'cloud'
90
66
  });
91
67
 
92
- // Retrieve a block
93
- const block = await client.agents.blocks.retrieve('human', { agent_id: agent.id });
68
+ const params: Letta.ArchiveCreateParams = { name: 'name' };
69
+ const archive: Letta.Archive = await client.archives.create(params);
94
70
  ```
95
71
 
96
- ### Multi-agent Shared Memory ([full guide](https://docs.letta.com/guides/agents/multi-agent-shared-memory))
72
+ Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
73
+
74
+ ## File uploads
75
+
76
+ Request parameters that correspond to file uploads can be passed in many different forms:
77
+
78
+ - `File` (or an object with the same structure)
79
+ - a `fetch` `Response` (or an object with the same structure)
80
+ - an `fs.ReadStream`
81
+ - the return value of our `toFile` helper
97
82
 
98
- Memory blocks can be attached to multiple agents. All agents will have an up-to-date view on the contents of the memory block -- if one agent modifies it, the other will see it immediately.
83
+ ```ts
84
+ import fs from 'fs';
85
+ import Letta, { toFile } from '@letta-ai/letta-client';
99
86
 
100
- Here is how to attach a single memory block to multiple agents:
87
+ const client = new Letta();
101
88
 
102
- ```typescript
103
- // Create shared block
104
- const sharedBlock = await client.blocks.create({
105
- label: 'organization',
106
- value: 'Shared team context',
89
+ // If you have access to Node `fs` we recommend using `fs.createReadStream()`:
90
+ await client.agents.importFile({ file: fs.createReadStream('/path/to/file') });
91
+
92
+ // Or if you have the web `File` API you can pass a `File` instance:
93
+ await client.agents.importFile({ file: new File(['my bytes'], 'file') });
94
+
95
+ // You can also pass a `fetch` `Response`:
96
+ await client.agents.importFile({ file: await fetch('https://somesite/file') });
97
+
98
+ // Finally, if none of the above are convenient, you can use our `toFile` helper:
99
+ await client.agents.importFile({ file: await toFile(Buffer.from('my bytes'), 'file') });
100
+ await client.agents.importFile({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
101
+ ```
102
+
103
+ ## Handling errors
104
+
105
+ When the library is unable to connect to the API,
106
+ or if the API returns a non-success status code (i.e., 4xx or 5xx response),
107
+ a subclass of `APIError` will be thrown:
108
+
109
+ <!-- prettier-ignore -->
110
+ ```ts
111
+ const archive = await client.archives.create({ name: 'name' }).catch(async (err) => {
112
+ if (err instanceof Letta.APIError) {
113
+ console.log(err.status); // 400
114
+ console.log(err.name); // BadRequestError
115
+ console.log(err.headers); // {server: 'nginx', ...}
116
+ } else {
117
+ throw err;
118
+ }
107
119
  });
120
+ ```
121
+
122
+ Error codes are as follows:
123
+
124
+ | Status Code | Error Type |
125
+ | ----------- | -------------------------- |
126
+ | 400 | `BadRequestError` |
127
+ | 401 | `AuthenticationError` |
128
+ | 403 | `PermissionDeniedError` |
129
+ | 404 | `NotFoundError` |
130
+ | 422 | `UnprocessableEntityError` |
131
+ | 429 | `RateLimitError` |
132
+ | >=500 | `InternalServerError` |
133
+ | N/A | `APIConnectionError` |
134
+
135
+ ### Retries
108
136
 
109
- // Attach to multiple agents
110
- const agent1 = await client.agents.create({
111
- memory_blocks: [{ label: 'persona', value: 'I am a supervisor' }],
112
- block_ids: [sharedBlock.id],
137
+ Certain errors will be automatically retried 2 times by default, with a short exponential backoff.
138
+ Connection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,
139
+ 429 Rate Limit, and >=500 Internal errors will all be retried by default.
140
+
141
+ You can use the `maxRetries` option to configure or disable this:
142
+
143
+ <!-- prettier-ignore -->
144
+ ```js
145
+ // Configure the default for all requests:
146
+ const client = new Letta({
147
+ maxRetries: 0, // default is 2
113
148
  });
114
149
 
115
- const agent2 = await client.agents.create({
116
- memory_blocks: [{ label: 'persona', value: 'I am a worker' }],
117
- block_ids: [sharedBlock.id],
150
+ // Or, configure per-request:
151
+ await client.archives.create({ name: 'name' }, {
152
+ maxRetries: 5,
118
153
  });
119
154
  ```
120
155
 
121
- ### Sleep-time Agents ([full guide](https://docs.letta.com/guides/agents/architectures/sleeptime))
156
+ ### Timeouts
157
+
158
+ Requests time out after 1 minute by default. You can configure this with a `timeout` option:
122
159
 
123
- Background agents that share memory with your primary agent:
160
+ <!-- prettier-ignore -->
161
+ ```ts
162
+ // Configure the default for all requests:
163
+ const client = new Letta({
164
+ timeout: 20 * 1000, // 20 seconds (default is 1 minute)
165
+ });
124
166
 
125
- ```typescript
126
- const agent = await client.agents.create({
127
- model: 'openai/gpt-4.1',
128
- enable_sleeptime: true, // creates a sleep-time agent
167
+ // Override per-request:
168
+ await client.archives.create({ name: 'name' }, {
169
+ timeout: 5 * 1000,
129
170
  });
130
171
  ```
131
172
 
132
- ### Agent File Import/Export ([full guide](https://docs.letta.com/guides/agents/agent-file))
173
+ On timeout, an `APIConnectionTimeoutError` is thrown.
133
174
 
134
- Save and share agents with the `.af` file format:
175
+ Note that requests which time out will be [retried twice by default](#retries).
135
176
 
136
- ```typescript
137
- import { readFileSync } from 'fs';
177
+ ## Auto-pagination
138
178
 
139
- // Import agent
140
- const file = new Blob([readFileSync('/path/to/agent.af')]);
141
- const agent = await client.agents.importFile(file);
179
+ List methods in the Letta API are paginated.
180
+ You can use the `for await … of` syntax to iterate through items across all pages:
142
181
 
143
- // Export agent
144
- const schema = await client.agents.exportFile(agent.id);
182
+ ```ts
183
+ async function fetchAllAgentStates(params) {
184
+ const allAgentStates = [];
185
+ // Automatically fetches more pages as needed.
186
+ for await (const agentState of client.agents.list()) {
187
+ allAgentStates.push(agentState);
188
+ }
189
+ return allAgentStates;
190
+ }
145
191
  ```
146
192
 
147
- ### MCP Tools ([full guide](https://docs.letta.com/guides/mcp/overview))
193
+ Alternatively, you can request a single page at a time:
148
194
 
149
- Connect to Model Context Protocol servers:
195
+ ```ts
196
+ let page = await client.agents.list();
197
+ for (const agentState of page.items) {
198
+ console.log(agentState);
199
+ }
150
200
 
151
- ```typescript
152
- // First, create an MCP server (example: weather server)
153
- const weatherServer = await client.mcpServers.create({
154
- server_name: 'weather-server',
155
- config: {
156
- mcp_server_type: 'streamable_http',
157
- server_url: 'https://weather-mcp.example.com/mcp',
158
- },
159
- });
201
+ // Convenience methods are provided for manually paginating:
202
+ while (page.hasNextPage()) {
203
+ page = await page.getNextPage();
204
+ // ...
205
+ }
206
+ ```
160
207
 
161
- // List tools available from the MCP server
162
- const tools = await client.mcpServers.tools.list(weatherServer.id);
208
+ ## Advanced Usage
163
209
 
164
- // Create agent with MCP tool
165
- const agent = await client.agents.create({
166
- model: 'openai/gpt-4.1',
167
- tool_ids: [tool.id],
168
- });
210
+ ### Accessing raw Response data (e.g., headers)
211
+
212
+ The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
213
+ This method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic.
214
+
215
+ You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.
216
+ Unlike `.asResponse()` this method consumes the body, returning once it is parsed.
217
+
218
+ <!-- prettier-ignore -->
219
+ ```ts
220
+ const client = new Letta();
221
+
222
+ const response = await client.archives.create({ name: 'name' }).asResponse();
223
+ console.log(response.headers.get('X-My-Header'));
224
+ console.log(response.statusText); // access the underlying Response object
225
+
226
+ const { data: archive, response: raw } = await client.archives
227
+ .create({ name: 'name' })
228
+ .withResponse();
229
+ console.log(raw.headers.get('X-My-Header'));
230
+ console.log(archive.id);
169
231
  ```
170
232
 
171
- ### Filesystem ([full guide](https://docs.letta.com/guides/agents/filesystem))
233
+ ### Logging
172
234
 
173
- Give agents access to files:
235
+ > [!IMPORTANT]
236
+ > All log messages are intended for debugging only. The format and content of log messages
237
+ > may change between releases.
174
238
 
175
- ```typescript
176
- import { createReadStream } from 'fs';
239
+ #### Log levels
177
240
 
178
- // Create folder and upload file
179
- const folder = await client.folders.create({
180
- name: 'my_folder',
181
- });
241
+ The log level can be configured in two ways:
242
+
243
+ 1. Via the `LETTA_LOG` environment variable
244
+ 2. Using the `logLevel` client option (overrides the environment variable if set)
182
245
 
183
- await client.folders.files.upload(createReadStream('file.txt'), folder.id);
246
+ ```ts
247
+ import Letta from '@letta-ai/letta-client';
184
248
 
185
- // Attach to agent
186
- await client.agents.folders.attach(agent.id, folder.id);
249
+ const client = new Letta({
250
+ logLevel: 'debug', // Show all log messages
251
+ });
187
252
  ```
188
253
 
189
- ### Long-running Agents ([full guide](https://docs.letta.com/guides/agents/long-running))
254
+ Available log levels, from most to least verbose:
190
255
 
191
- Background execution with resumable streaming:
256
+ - `'debug'` - Show debug messages, info, warnings, and errors
257
+ - `'info'` - Show info messages, warnings, and errors
258
+ - `'warn'` - Show warnings and errors (default)
259
+ - `'error'` - Show only errors
260
+ - `'off'` - Disable all logging
192
261
 
193
- ```typescript
194
- const stream = await client.agents.messages.create(agent.id, {
195
- messages: [{ role: 'user', content: 'Analyze this dataset' }],
196
- background: true,
197
- });
262
+ At the `'debug'` level, all HTTP requests and responses are logged, including headers and bodies.
263
+ Some authentication-related headers are redacted, but sensitive data in request and response bodies
264
+ may still be visible.
198
265
 
199
- let run_id, last_seq_id;
200
- for await (const chunk of stream) {
201
- run_id = chunk.run_id;
202
- last_seq_id = chunk.seq_id;
203
- }
266
+ #### Custom logger
204
267
 
205
- // Resume if disconnected
206
- for await (const chunk of client.runs.stream(run_id, { starting_after: last_seq_id })) {
207
- console.log(chunk);
208
- }
209
- ```
268
+ By default, this library logs to `globalThis.console`. You can also provide a custom logger.
269
+ Most logging libraries are supported, including [pino](https://www.npmjs.com/package/pino), [winston](https://www.npmjs.com/package/winston), [bunyan](https://www.npmjs.com/package/bunyan), [consola](https://www.npmjs.com/package/consola), [signale](https://www.npmjs.com/package/signale), and [@std/log](https://jsr.io/@std/log). If your logger doesn't work, please open an issue.
210
270
 
211
- ### Streaming ([full guide](https://docs.letta.com/guides/agents/streaming))
271
+ When providing a custom logger, the `logLevel` option still controls which messages are emitted, messages
272
+ below the configured level will not be sent to your logger.
212
273
 
213
- Stream responses in real-time:
274
+ ```ts
275
+ import Letta from '@letta-ai/letta-client';
276
+ import pino from 'pino';
214
277
 
215
- ```typescript
216
- const stream = await client.agents.messages.stream(agent.id, {
217
- messages: [{ role: 'user', content: 'Hello!' }],
278
+ const logger = pino();
279
+
280
+ const client = new Letta({
281
+ logger: logger.child({ name: 'Letta' }),
282
+ logLevel: 'debug', // Send all messages to pino, allowing it to filter
218
283
  });
284
+ ```
219
285
 
220
- for await (const chunk of stream) {
221
- console.log(chunk);
222
- }
286
+ ### Making custom/undocumented requests
287
+
288
+ This library is typed for convenient access to the documented API. If you need to access undocumented
289
+ endpoints, params, or response properties, the library can still be used.
290
+
291
+ #### Undocumented endpoints
292
+
293
+ To make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.
294
+ Options on the client, such as retries, will be respected when making these requests.
295
+
296
+ ```ts
297
+ await client.post('/some/path', {
298
+ body: { some_prop: 'foo' },
299
+ query: { some_query_arg: 'bar' },
300
+ });
223
301
  ```
224
302
 
225
- ### Message Types ([full guide](https://docs.letta.com/guides/agents/message-types))
226
-
227
- Agent responses contain different message types. Handle them with the `message_type` discriminator:
228
-
229
- ```typescript
230
- const messagesPage = await client.agents.messages.list(agent.id);
231
-
232
- for await (const message of messagesPage) {
233
- switch (message.message_type) {
234
- case 'user_message':
235
- console.log('User:', message.content);
236
- break;
237
- case 'assistant_message':
238
- console.log('Agent:', message.content);
239
- break;
240
- case 'reasoning_message':
241
- console.log('Reasoning:', message.reasoning);
242
- break;
243
- case 'tool_call_message':
244
- console.log('Tool:', message.tool_call.name);
245
- break;
246
- case 'tool_return_message':
247
- console.log('Result:', message.tool_return);
248
- break;
249
- }
250
- }
303
+ #### Undocumented request params
304
+
305
+ To make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented
306
+ parameter. This library doesn't validate at runtime that the request matches the type, so any extra values you
307
+ send will be sent as-is.
308
+
309
+ ```ts
310
+ client.archives.create({
311
+ // ...
312
+ // @ts-expect-error baz is not yet public
313
+ baz: 'undocumented option',
314
+ });
251
315
  ```
252
316
 
253
- ## TypeScript Support
317
+ For requests with the `GET` verb, any extra params will be in the query, all other requests will send the
318
+ extra param in the body.
319
+
320
+ If you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request
321
+ options.
322
+
323
+ #### Undocumented response properties
254
324
 
255
- Full TypeScript support with exported types:
325
+ To access undocumented response properties, you may access the response object with `// @ts-expect-error` on
326
+ the response object, or cast the response object to the requisite type. Like the request params, we do not
327
+ validate or strip extra properties from the response from the API.
256
328
 
257
- ```typescript
258
- import { Letta } from "@letta-ai/letta-client";
329
+ ### Customizing the fetch client
259
330
 
260
- const request: Letta.CreateAgentRequest = {
261
- model: "openai/gpt-4.1",
262
- memory_blocks: [...]
263
- };
331
+ By default, this library expects a global `fetch` function is defined.
332
+
333
+ If you want to use a different `fetch` function, you can either polyfill the global:
334
+
335
+ ```ts
336
+ import fetch from 'my-fetch';
337
+
338
+ globalThis.fetch = fetch;
264
339
  ```
265
340
 
266
- ## Error Handling
341
+ Or pass it to the client:
267
342
 
268
- ```typescript
269
- import { LettaError } from "@letta-ai/letta-client";
343
+ ```ts
344
+ import Letta from '@letta-ai/letta-client';
345
+ import fetch from 'my-fetch';
270
346
 
271
- try {
272
- await client.agents.messages.create(agentId, {...});
273
- } catch (err) {
274
- if (err instanceof LettaError) {
275
- console.log(err.statusCode);
276
- console.log(err.message);
277
- console.log(err.body);
278
- }
279
- }
347
+ const client = new Letta({ fetch });
280
348
  ```
281
349
 
282
- ## Advanced Configuration
350
+ ### Fetch options
283
351
 
284
- ### Retries
352
+ If you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.)
353
+
354
+ ```ts
355
+ import Letta from '@letta-ai/letta-client';
285
356
 
286
- ```typescript
287
- const response = await client.agents.create({...}, {
288
- maxRetries: 3 // Default: 2
357
+ const client = new Letta({
358
+ fetchOptions: {
359
+ // `RequestInit` options
360
+ },
289
361
  });
290
362
  ```
291
363
 
292
- ### Timeouts
364
+ #### Configuring proxies
365
+
366
+ To modify proxy behavior, you can provide custom `fetchOptions` that add runtime-specific proxy
367
+ options to requests:
368
+
369
+ <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/node.svg" align="top" width="18" height="21"> **Node** <sup>[[docs](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md#example---proxyagent-with-fetch)]</sup>
293
370
 
294
- ```typescript
295
- const response = await client.agents.create({...}, {
296
- timeoutInSeconds: 30 // Default: 60
371
+ ```ts
372
+ import Letta from '@letta-ai/letta-client';
373
+ import * as undici from 'undici';
374
+
375
+ const proxyAgent = new undici.ProxyAgent('http://localhost:8888');
376
+ const client = new Letta({
377
+ fetchOptions: {
378
+ dispatcher: proxyAgent,
379
+ },
297
380
  });
298
381
  ```
299
382
 
300
- ### Custom Headers
383
+ <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/bun.svg" align="top" width="18" height="21"> **Bun** <sup>[[docs](https://bun.sh/guides/http/proxy)]</sup>
301
384
 
302
- ```typescript
303
- const response = await client.agents.create({...}, {
304
- headers: {
305
- 'X-Custom-Header': 'value'
306
- }
385
+ ```ts
386
+ import Letta from '@letta-ai/letta-client';
387
+
388
+ const client = new Letta({
389
+ fetchOptions: {
390
+ proxy: 'http://localhost:8888',
391
+ },
307
392
  });
308
393
  ```
309
394
 
310
- ## Contributing
395
+ <img src="https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/deno.svg" align="top" width="18" height="21"> **Deno** <sup>[[docs](https://docs.deno.com/api/deno/~/Deno.createHttpClient)]</sup>
396
+
397
+ ```ts
398
+ import Letta from 'npm:@letta-ai/letta-client';
399
+
400
+ const httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } });
401
+ const client = new Letta({
402
+ fetchOptions: {
403
+ client: httpClient,
404
+ },
405
+ });
406
+ ```
311
407
 
312
- Letta is an open source project built by over a hundred contributors. There are many ways to get involved in the Letta OSS project!
408
+ ## Frequently Asked Questions
313
409
 
314
- - [**Join the Discord**](https://discord.gg/letta): Chat with the Letta devs and other AI developers.
315
- - [**Chat on our forum**](https://forum.letta.com/): If you're not into Discord, check out our developer forum.
316
- - **Follow our socials**: [Twitter/X](https://twitter.com/Letta_AI), [LinkedIn](https://www.linkedin.com/company/letta-ai/), [YouTube](https://www.youtube.com/@letta-ai)
410
+ ## Semantic versioning
317
411
 
318
- This SDK is generated programmatically. For SDK changes, please [open an issue](https://github.com/letta-ai/letta-node/issues).
412
+ This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:
319
413
 
320
- README contributions are always welcome!
414
+ 1. Changes that only affect static types, without breaking runtime behavior.
415
+ 2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_
416
+ 3. Changes that we do not expect to impact the vast majority of users in practice.
321
417
 
322
- ## Resources
418
+ We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.
323
419
 
324
- - [Documentation](https://docs.letta.com)
325
- - [TypeScript API Reference](./reference.md)
326
- - [Example Applications](https://github.com/letta-ai/letta-chatbot-example)
420
+ We are keen for your feedback; please open an [issue](https://www.github.com/letta-ai/letta-node/issues) with questions, bugs, or suggestions.
327
421
 
328
- ## License
422
+ ## Requirements
329
423
 
330
- MIT
424
+ TypeScript >= 4.9 is supported.
331
425
 
332
- ---
426
+ The following runtimes are supported:
427
+
428
+ - Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more)
429
+ - Node.js 20 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.
430
+ - Deno v1.28.0 or higher.
431
+ - Bun 1.0 or later.
432
+ - Cloudflare Workers.
433
+ - Vercel Edge Runtime.
434
+ - Jest 28 or greater with the `"node"` environment (`"jsdom"` is not supported at this time).
435
+ - Nitro v2.6 or greater.
436
+
437
+ Note that React Native is not supported at this time.
438
+
439
+ If you are interested in other runtime environments, please open or upvote an issue on GitHub.
440
+
441
+ ## Contributing
333
442
 
334
- **\*Legal notices**: By using Letta and related Letta services (such as the Letta endpoint or hosted service), you are agreeing to our [privacy policy](https://www.letta.com/privacy-policy) and [terms of service](https://www.letta.com/terms-of-service).\*
443
+ See [the contributing documentation](./CONTRIBUTING.md).