@letta-ai/letta-code-sdk 0.0.4 → 0.0.6

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 CHANGED
@@ -2,20 +2,11 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@letta-ai/letta-code-sdk.svg?style=flat-square)](https://www.npmjs.com/package/@letta-ai/letta-code-sdk) [![Discord](https://img.shields.io/badge/discord-join-blue?style=flat-square&logo=discord)](https://discord.gg/letta)
4
4
 
5
- > [!TIP]
6
- > Check out [**LettaBot**](https://github.com/letta-ai/lettabot) and [**Letta Cowork**](github.com/letta-ai/letta-cowork), two open-source apps built on the **Letta Code SDK**.
7
-
8
- The SDK interface to [**Letta Code**](https://github.com/letta-ai/letta-code). Build agents with persistent memory that learn over time.
9
5
 
10
- ```typescript
11
- import { createSession } from '@letta-ai/letta-code-sdk';
6
+ The SDK interface to [**Letta Code**](https://github.com/letta-ai/letta-code). Build agents with persistent memory that learn over time.
12
7
 
13
- const session = createSession();
14
- await session.send('Find and fix the bug in auth.py');
15
- for await (const msg of session.stream()) {
16
- if (msg.type === 'assistant') console.log(msg.content);
17
- }
18
- ```
8
+ > [!TIP]
9
+ > Check out [**LettaBot**](https://github.com/letta-ai/lettabot) and [**Letta Cowork**](https://github.com/letta-ai/letta-cowork), two open-source apps built on the SDK.
19
10
 
20
11
  ## Installation
21
12
 
@@ -23,302 +14,46 @@ for await (const msg of session.stream()) {
23
14
  npm install @letta-ai/letta-code-sdk
24
15
  ```
25
16
 
26
- ## Quick Start
17
+ ## Quick start
27
18
 
28
19
  ### One-shot prompt
29
20
 
30
- ```typescript
31
- import { prompt } from '@letta-ai/letta-code-sdk';
21
+ ```ts
22
+ import { prompt } from "@letta-ai/letta-code-sdk";
32
23
 
33
- // One-shot (uses default agent - like `letta -p`)
34
- const result = await prompt('What is 2 + 2?');
24
+ const result = await prompt("What is 2 + 2?");
35
25
  console.log(result.result);
36
-
37
- // One-shot with specific agent
38
- const result2 = await prompt('Run: echo hello', agentId);
39
26
  ```
40
27
 
41
- ### Multi-turn session
28
+ ### Persistent agent with multi-turn conversations
42
29
 
43
- ```typescript
44
- import { createAgent, resumeSession } from '@letta-ai/letta-code-sdk';
30
+ ```ts
31
+ import { createAgent, resumeSession } from "@letta-ai/letta-code-sdk";
45
32
 
46
- // Create an agent (has default conversation)
47
- const agentId = await createAgent();
33
+ const agentId = await createAgent({
34
+ persona: "You are a helpful coding assistant for TypeScript projects.",
35
+ });
48
36
 
49
- // Resume the default conversation
50
37
  await using session = resumeSession(agentId);
51
38
 
52
- await session.send('What is 5 + 3?');
39
+ await session.send("Find and fix the bug in auth.ts");
53
40
  for await (const msg of session.stream()) {
54
- if (msg.type === 'assistant') console.log(msg.content);
41
+ if (msg.type === "assistant") console.log(msg.content);
55
42
  }
56
43
 
57
- await session.send('Multiply that by 2');
44
+ await session.send("Add a unit test for the fix");
58
45
  for await (const msg of session.stream()) {
59
- if (msg.type === 'assistant') console.log(msg.content);
46
+ if (msg.type === "assistant") console.log(msg.content);
60
47
  }
61
48
  ```
62
49
 
63
- ### Persistent memory
64
-
65
- Agents persist across sessions and remember context:
66
-
67
- ```typescript
68
- import { createAgent, resumeSession } from '@letta-ai/letta-code-sdk';
69
-
70
- // Create agent and teach it something
71
- const agentId = await createAgent();
72
- const session1 = resumeSession(agentId);
73
- await session1.send('Remember: the secret word is "banana"');
74
- for await (const msg of session1.stream()) { /* ... */ }
75
- session1.close();
76
-
77
- // Later... resume the default conversation
78
- await using session2 = resumeSession(agentId);
79
- await session2.send('What is the secret word?');
80
- for await (const msg of session2.stream()) {
81
- if (msg.type === 'assistant') console.log(msg.content); // "banana"
82
- }
83
- ```
84
-
85
- ## Multi-threaded Conversations
86
-
87
- Run multiple concurrent conversations with the same agent. Each conversation has its own message history while sharing the agent's persistent memory.
88
-
89
- ```typescript
90
- import { createAgent, createSession, resumeSession } from '@letta-ai/letta-code-sdk';
91
-
92
- // Create an agent (has default conversation)
93
- const agentId = await createAgent();
94
-
95
- // Resume the default conversation
96
- const session1 = resumeSession(agentId);
97
- await session1.send('Hello!');
98
- for await (const msg of session1.stream()) { /* ... */ }
99
- const conversationId = session1.conversationId; // Save this!
100
- session1.close();
101
-
102
- // Resume a specific conversation by ID
103
- await using session2 = resumeSession(conversationId); // auto-detects conv-xxx
104
- await session2.send('Continue our discussion...');
105
- for await (const msg of session2.stream()) { /* ... */ }
106
-
107
- // Create a NEW conversation on the same agent
108
- await using session3 = createSession(agentId);
109
- await session3.send('Start a fresh thread...');
110
- // session3.conversationId is different from conversationId
111
-
112
- // Start fresh conversation with default agent
113
- await using session4 = createSession();
114
- ```
115
-
116
- **Key concepts:**
117
- - **Agent** (`agentId`): Persistent entity with memory that survives across sessions
118
- - **Conversation** (`conversationId`): A message thread within an agent
119
- - **Session**: A single execution/connection
120
- - **Default conversation**: Always exists after `createAgent()` - use `resumeSession(agentId)` to access it
121
-
122
- Agents remember across conversations (via memory blocks), but each conversation has its own message history.
123
-
124
- ## Session Configuration
125
-
126
- ### System Prompt
127
-
128
- Choose from built-in presets or provide a custom prompt:
129
-
130
- ```typescript
131
- // Use a preset
132
- createSession(agentId, {
133
- systemPrompt: { type: 'preset', preset: 'letta-claude' }
134
- });
135
-
136
- // Use a preset with additional instructions
137
- createSession(agentId, {
138
- systemPrompt: {
139
- type: 'preset',
140
- preset: 'letta-claude',
141
- append: 'Always respond in Spanish.'
142
- }
143
- });
144
-
145
- // Use a completely custom prompt
146
- createSession(agentId, {
147
- systemPrompt: 'You are a helpful Python expert.'
148
- });
149
- ```
150
-
151
- **Available presets:**
152
- - `default` / `letta-claude` - Full Letta Code prompt (Claude-optimized)
153
- - `letta-codex` - Full Letta Code prompt (Codex-optimized)
154
- - `letta-gemini` - Full Letta Code prompt (Gemini-optimized)
155
- - `claude` - Basic Claude (no skills/memory instructions)
156
- - `codex` - Basic Codex
157
- - `gemini` - Basic Gemini
158
-
159
- ### Memory Blocks
160
-
161
- Configure which memory blocks the session uses:
162
-
163
- ```typescript
164
- // Use default blocks (persona, human, project)
165
- createSession(agentId);
166
-
167
- // Use specific preset blocks
168
- createSession(agentId, {
169
- memory: ['project', 'persona'] // Only these blocks
170
- });
171
-
172
- // Use custom blocks
173
- createSession(agentId, {
174
- memory: [
175
- { label: 'context', value: 'API documentation for Acme Corp...' },
176
- { label: 'rules', value: 'Always use TypeScript. Prefer functional patterns.' }
177
- ]
178
- });
179
-
180
- // No optional blocks (only core skills blocks)
181
- createSession(agentId, {
182
- memory: []
183
- });
184
- ```
185
-
186
- ### Convenience Props
187
-
188
- Quickly customize common memory blocks:
189
-
190
- ```typescript
191
- createSession(agentId, {
192
- persona: 'You are a senior Python developer who writes clean, tested code.',
193
- human: 'Name: Alice. Prefers concise responses.',
194
- project: 'FastAPI backend for a todo app using PostgreSQL.'
195
- });
196
- ```
197
-
198
- ### Tool Execution
199
-
200
- Execute tools with automatic permission handling:
201
-
202
- ```typescript
203
- import { createAgent, createSession } from '@letta-ai/letta-code-sdk';
204
-
205
- // Create agent and run commands
206
- const agentId = await createAgent();
207
- const session = createSession(agentId, {
208
- allowedTools: ['Glob', 'Bash'],
209
- permissionMode: 'bypassPermissions',
210
- cwd: '/path/to/project'
211
- });
212
- await session.send('List all TypeScript files');
213
- for await (const msg of session.stream()) { /* ... */ }
214
- ```
215
-
216
- ## API Reference
217
-
218
- ### Functions
219
-
220
- | Function | Description |
221
- |----------|-------------|
222
- | `createAgent()` | Create new agent with default conversation, returns `agentId` |
223
- | `createSession()` | New conversation on default agent |
224
- | `createSession(agentId)` | New conversation on specified agent |
225
- | `resumeSession(id, options?)` | Resume session - pass `agent-xxx` for default conv, `conv-xxx` for specific conv |
226
- | `prompt(message)` | One-shot query with default agent (like `letta -p`) |
227
- | `prompt(message, agentId)` | One-shot query with specific agent |
228
-
229
- ### Session
230
-
231
- | Property/Method | Description |
232
- |-----------------|-------------|
233
- | `send(message)` | Send user message |
234
- | `stream()` | AsyncGenerator yielding messages |
235
- | `close()` | Close the session |
236
- | `agentId` | Agent ID (for resuming later) |
237
- | `sessionId` | Current session ID |
238
- | `conversationId` | Conversation ID (for resuming specific thread) |
239
-
240
- ### Options
241
-
242
- ```typescript
243
- interface SessionOptions {
244
- model?: string;
245
- systemPrompt?: string | { type: 'preset'; preset: string; append?: string };
246
- memory?: Array<string | CreateBlock | { blockId: string }>;
247
- persona?: string;
248
- human?: string;
249
- project?: string;
250
- cwd?: string;
251
-
252
- // Tool configuration
253
- allowedTools?: string[];
254
- permissionMode?: 'default' | 'acceptEdits' | 'bypassPermissions';
255
- canUseTool?: (toolName: string, toolInput: object) => Promise<CanUseToolResponse>;
256
- maxTurns?: number;
257
- }
258
- ```
259
-
260
- ### Message Types
261
-
262
- ```typescript
263
- // Streamed during receive()
264
- interface SDKAssistantMessage {
265
- type: 'assistant';
266
- content: string;
267
- uuid: string;
268
- }
269
-
270
- // Final message
271
- interface SDKResultMessage {
272
- type: 'result';
273
- success: boolean;
274
- result?: string;
275
- error?: string;
276
- durationMs: number;
277
- conversationId: string;
278
- }
279
- ```
280
-
281
- ## Examples
282
-
283
- See [`examples/`](./examples/) for comprehensive examples including:
284
-
285
- - Basic session usage
286
- - Multi-turn conversations
287
- - Session resume with persistent memory
288
- - **Multi-threaded conversations** (createSession, resumeSession)
289
- - System prompt configuration
290
- - Memory block customization
291
- - Tool execution (Bash, Glob, Read, etc.)
292
-
293
- Run examples:
294
- ```bash
295
- bun examples/v2-examples.ts all
296
-
297
- # Run just conversation tests
298
- bun examples/v2-examples.ts conversations
299
- ```
300
-
301
- ## Internals
302
-
303
- ### CLI Mapping
304
-
305
- The SDK spawns the Letta Code CLI as a subprocess. Here's how API calls map to CLI flags:
50
+ By default, `resumeSession(agentId)` continues the agent’s default conversation. To start a fresh thread, use `createSession(agentId)` (see docs).
306
51
 
307
- | Function | CLI Flags | Behavior |
308
- |----------|-----------|----------|
309
- | `createSession()` | `--new` | LRU agent + new conversation |
310
- | `createSession(agentId)` | `--agent X --new` | Specified agent + new conversation |
311
- | `createAgent()` | `--new-agent` | New agent + default conversation |
312
- | `resumeSession(agentId)` | `--agent X --default` | Specified agent + default conversation |
313
- | `resumeSession(convId)` | `--conversation X` | Derived agent + specified conversation |
314
- | `prompt(msg)` | *(none)* | LRU agent + default conversation |
315
- | `prompt(msg, agentId)` | `--agent X --new` | Specified agent + new conversation |
52
+ ## Links
316
53
 
317
- **Key concepts:**
318
- - **LRU agent**: Most recently used agent from `.letta/settings.local.json`, or creates "Memo" if none exists
319
- - **Default conversation**: The agent's primary message history (always exists)
320
- - **New conversation**: Fresh message thread, isolated from other conversations
54
+ - Docs: https://docs.letta.com/letta-code-sdk
55
+ - Examples: [`./examples`](./examples)
321
56
 
322
- ## License
57
+ ---
323
58
 
324
- Apache-2.0
59
+ Made with 💜 in San Francisco
package/dist/index.d.ts CHANGED
@@ -28,22 +28,31 @@
28
28
  * ```
29
29
  */
30
30
  import { Session } from "./session.js";
31
- import type { SessionOptions, SDKResultMessage } from "./types.js";
32
- export type { SessionOptions, SDKMessage, SDKInitMessage, SDKAssistantMessage, SDKToolCallMessage, SDKToolResultMessage, SDKReasoningMessage, SDKResultMessage, SDKStreamEventMessage, PermissionMode, CanUseToolCallback, CanUseToolResponse, CanUseToolResponseAllow, CanUseToolResponseDeny, } from "./types.js";
31
+ import type { CreateSessionOptions, CreateAgentOptions, SDKResultMessage } from "./types.js";
32
+ export type { CreateSessionOptions, CreateAgentOptions, SDKMessage, SDKInitMessage, SDKAssistantMessage, SDKToolCallMessage, SDKToolResultMessage, SDKReasoningMessage, SDKResultMessage, SDKStreamEventMessage, PermissionMode, CanUseToolCallback, CanUseToolResponse, CanUseToolResponseAllow, CanUseToolResponseDeny, TextContent, ImageContent, MessageContentItem, SendMessage, AgentTool, AgentToolResult, AgentToolResultContent, AgentToolUpdateCallback, AnyAgentTool, } from "./types.js";
33
33
  export { Session } from "./session.js";
34
+ export { jsonResult, readStringParam, readNumberParam, readBooleanParam, readStringArrayParam, } from "./tool-helpers.js";
34
35
  /**
35
36
  * Create a new agent with a default conversation.
36
37
  * Returns the agentId which can be used with resumeSession or createSession.
37
38
  *
38
39
  * @example
39
40
  * ```typescript
41
+ * // Create agent with default settings
40
42
  * const agentId = await createAgent();
41
43
  *
44
+ * // Create agent with custom memory
45
+ * const agentId = await createAgent({
46
+ * memory: ['persona', 'project'],
47
+ * persona: 'You are a helpful coding assistant',
48
+ * model: 'claude-sonnet-4'
49
+ * });
50
+ *
42
51
  * // Then resume the default conversation:
43
52
  * const session = resumeSession(agentId);
44
53
  * ```
45
54
  */
46
- export declare function createAgent(): Promise<string>;
55
+ export declare function createAgent(options?: CreateAgentOptions): Promise<string>;
47
56
  /**
48
57
  * Create a new conversation (session).
49
58
  *
@@ -59,7 +68,7 @@ export declare function createAgent(): Promise<string>;
59
68
  * await using session = createSession(agentId);
60
69
  * ```
61
70
  */
62
- export declare function createSession(agentId?: string, options?: SessionOptions): Session;
71
+ export declare function createSession(agentId?: string, options?: CreateSessionOptions): Session;
63
72
  /**
64
73
  * Resume an existing session.
65
74
  *
@@ -78,7 +87,7 @@ export declare function createSession(agentId?: string, options?: SessionOptions
78
87
  * await using session = resumeSession('conv-xxx');
79
88
  * ```
80
89
  */
81
- export declare function resumeSession(id: string, options?: SessionOptions): Session;
90
+ export declare function resumeSession(id: string, options?: CreateSessionOptions): Session;
82
91
  /**
83
92
  * One-shot prompt convenience function.
84
93
  *
@@ -92,4 +101,44 @@ export declare function resumeSession(id: string, options?: SessionOptions): Ses
92
101
  * ```
93
102
  */
94
103
  export declare function prompt(message: string, agentId?: string): Promise<SDKResultMessage>;
104
+ import type { ImageContent } from "./types.js";
105
+ /**
106
+ * Create image content from a file path.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * await session.send([
111
+ * { type: "text", text: "What's in this image?" },
112
+ * imageFromFile("./screenshot.png")
113
+ * ]);
114
+ * ```
115
+ */
116
+ export declare function imageFromFile(filePath: string): ImageContent;
117
+ /**
118
+ * Create image content from base64 data.
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const base64 = fs.readFileSync("image.png").toString("base64");
123
+ * await session.send([
124
+ * { type: "text", text: "Describe this" },
125
+ * imageFromBase64(base64, "image/png")
126
+ * ]);
127
+ * ```
128
+ */
129
+ export declare function imageFromBase64(data: string, media_type?: ImageContent["source"]["media_type"]): ImageContent;
130
+ /**
131
+ * Create image content from a URL.
132
+ * Fetches the image and converts to base64.
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const img = await imageFromURL("https://example.com/image.png");
137
+ * await session.send([
138
+ * { type: "text", text: "What's this?" },
139
+ * img
140
+ * ]);
141
+ * ```
142
+ */
143
+ export declare function imageFromURL(url: string): Promise<ImageContent>;
95
144
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAc,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/E,YAAY,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAKnD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAMrF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAMT;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CA+B3B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAI7F,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EAEtB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,WAAW,EAEX,SAAS,EACT,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EACL,UAAU,EACV,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAMnF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAO3F;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAOT;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CA+B3B;AAOD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAa5D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAe,GAC7D,YAAY,CAKd;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBrE"}