1520 lines
40 KiB
Plaintext
1520 lines
40 KiB
Plaintext
---
|
|
title: SDK v1.0 Migration Guide
|
|
subtitle: Upgrading from v0.x to v1.0
|
|
slug: api-reference/sdk-migration-guide
|
|
---
|
|
|
|
<Info>
|
|
This guide covers migrating from Letta SDK v0.x (e.g., `1.0.0-alpha.2`) to v1.0 (e.g., `1.0.0-alpha.10`+). For agent architecture migrations, see the [Architecture Migration Guide](/guides/legacy/migration_guide).
|
|
</Info>
|
|
|
|
<Warning>
|
|
**Letta Cloud Only (for now)**
|
|
|
|
This SDK v1.0 migration guide applies **only to Letta Cloud**.
|
|
|
|
The current self-hosted Letta release (v0.13.x) does **not** support the v1.0 SDK. If you are self-hosting Letta, continue using SDK v0.x for now.
|
|
|
|
**Coming soon:** We will be releasing a new open-source version of Letta that includes SDK v1.0 support for self-hosted deployments.
|
|
|
|
To use the v1.0 SDK today, you must connect to Letta Cloud at `https://api.letta.com`.
|
|
</Warning>
|
|
|
|
## Overview
|
|
|
|
SDK v1.0 introduces breaking changes to improve consistency and align with modern API design patterns:
|
|
|
|
- **Naming convention**: All properties now use `snake_case` instead of `camelCase`
|
|
- **Client initialization**: Simplified client constructor with renamed parameters
|
|
- **Method names**: Several methods renamed for clarity
|
|
- **Type imports**: Types moved to subpath exports for better organization
|
|
- **Enums**: Replaced with string literal types
|
|
- **Tool calls**: Changed from single object to array structure
|
|
- **Pagination**: List methods now return page objects
|
|
|
|
## Quick Reference
|
|
|
|
### Package Update
|
|
|
|
Update your package dependency:
|
|
|
|
<CodeGroup>
|
|
```json package.json
|
|
{
|
|
"dependencies": {
|
|
- "@letta-ai/letta-client": "1.0.0-alpha.2"
|
|
+ "@letta-ai/letta-client": "1.0.0-alpha.10"
|
|
}
|
|
}
|
|
```
|
|
```toml pyproject.toml
|
|
[tool.poetry.dependencies]
|
|
-letta-client = "1.0.0a2"
|
|
+letta-client = "1.0.0a10"
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Import Changes
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old
|
|
- import { LettaClient, Letta } from "@letta-ai/letta-client";
|
|
|
|
// New
|
|
+ import Letta from "@letta-ai/letta-client";
|
|
+ import type {
|
|
+ Block,
|
|
+ CreateBlock,
|
|
+ AgentType
|
|
+ } from "@letta-ai/letta-client/resources/agents/agents";
|
|
+ import type {
|
|
+ LettaMessageUnion,
|
|
+ ApprovalCreate
|
|
+ } from "@letta-ai/letta-client/resources/agents/messages";
|
|
+ import type {
|
|
+ LlmConfig
|
|
+ } from "@letta-ai/letta-client/resources/models/models";
|
|
```
|
|
```python Python
|
|
# Old
|
|
- from letta_client import Letta, LettaClient
|
|
|
|
# New
|
|
+ from letta import Letta
|
|
+ from letta.schemas.agent import Block, CreateBlock, AgentType
|
|
+ from letta.schemas.message import LettaMessageUnion, ApprovalCreate
|
|
+ from letta.schemas.llm_config import LlmConfig
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Client Instantiation
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old
|
|
- const client = new LettaClient({
|
|
- token: process.env.LETTA_API_KEY,
|
|
- baseUrl: "https://api.letta.com"
|
|
- });
|
|
|
|
// New
|
|
+ const client = new Letta({
|
|
+ apiKey: process.env.LETTA_API_KEY,
|
|
+ baseURL: "https://api.letta.com"
|
|
+ });
|
|
```
|
|
```python Python
|
|
# Old
|
|
- client = LettaClient(
|
|
- token=os.environ["LETTA_API_KEY"],
|
|
- base_url="https://api.letta.com"
|
|
- )
|
|
|
|
# New
|
|
+ client = Letta(
|
|
+ api_key=os.environ["LETTA_API_KEY"],
|
|
+ base_url="https://api.letta.com"
|
|
+ )
|
|
```
|
|
</CodeGroup>
|
|
|
|
## Breaking Changes by Category
|
|
|
|
### 1. Pagination
|
|
|
|
All list endpoints now use cursor-based pagination with consistent parameters:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old - various pagination styles
|
|
const messages = await client.agents.messages.list(agentId, {
|
|
sort_by: "created_at",
|
|
ascending: true
|
|
});
|
|
|
|
// New - standardized cursor pagination
|
|
const messagesPage = await client.agents.messages.list(agentId, {
|
|
before: "msg_123", // cursor (message ID)
|
|
after: "msg_456", // cursor (message ID)
|
|
limit: 50,
|
|
order: "asc" // or "desc"
|
|
});
|
|
const messages = messagesPage.items;
|
|
```
|
|
```python Python
|
|
# Old
|
|
messages = client.agents.messages.list(
|
|
agent_id=agent_id,
|
|
sort_by="created_at",
|
|
ascending=True
|
|
)
|
|
|
|
# New
|
|
messages_page = client.agents.messages.list(
|
|
agent_id=agent_id,
|
|
before="msg_123",
|
|
after="msg_456",
|
|
limit=50,
|
|
order="asc"
|
|
)
|
|
messages = messages_page.items
|
|
```
|
|
</CodeGroup>
|
|
|
|
**Affected endpoints:**
|
|
- `agents.list()` - renamed `sort_by` → `order_by`, `ascending` → `order`
|
|
- `agents.messages.list()`
|
|
- `agents.tools.list()`
|
|
- `agents.blocks.list()`
|
|
- `agents.files.list()`
|
|
- `agents.folders.list()`
|
|
- `agents.groups.list()`
|
|
- `blocks.list()`
|
|
- `folders.list()`
|
|
- `folders.files.list()`
|
|
- `folders.passages.list()`
|
|
- `folders.agents.list()`
|
|
- `groups.list()`
|
|
- `groups.messages.list()`
|
|
- `identities.list()`
|
|
- `providers.list()`
|
|
- `runs.list()`
|
|
- `runs.messages.list()`
|
|
- `runs.steps.list()`
|
|
- `jobs.list()`
|
|
- `steps.list()`
|
|
- `tags.list()`
|
|
- `tools.list()`
|
|
- `batches.list()`
|
|
- `batches.messages.list()`
|
|
|
|
### 2. Method Renames and Endpoint Restructuring
|
|
|
|
Many methods were reorganized for better SDK structure:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Agent updates
|
|
- await client.agents.modify(agentId, updates)
|
|
+ await client.agents.update(agentId, updates)
|
|
|
|
// Message operations
|
|
- await client.agents.summarize_agent_conversation(agentId)
|
|
+ await client.agents.messages.compact(agentId)
|
|
|
|
- await client.agents.cancel_agent_run(agentId)
|
|
+ await client.agents.messages.cancel(agentId)
|
|
|
|
- await client.agents.messages.preview_raw_payload(agentId, messages)
|
|
+ await client.agents.messages.preview(agentId, messages)
|
|
|
|
// Agent file operations
|
|
- await client.agents.list_agent_files(agentId)
|
|
+ await client.agents.files.list(agentId)
|
|
|
|
// Export/Import
|
|
- await client.agents.export_agent_serialized(agentId)
|
|
+ await client.agents.exportFile(agentId)
|
|
|
|
- await client.agents.import_agent_serialized(file)
|
|
+ await client.agents.importFile(file)
|
|
|
|
// Folder operations
|
|
- await client.folders.get_agents_for_folder(folderId)
|
|
+ await client.folders.agents.list(folderId)
|
|
|
|
- await client.folders.retrieve_folder_metadata(folderId)
|
|
+ await client.folders.retrieve_metadata(folderId)
|
|
|
|
// Provider operations
|
|
- await client.providers.check_provider(providerId)
|
|
+ await client.providers.check(providerId)
|
|
|
|
// Telemetry
|
|
- await client.telemetry.retrieve_provider_trace(stepId)
|
|
+ await client.steps.trace(stepId)
|
|
|
|
// Step metrics
|
|
- await client.steps.retrieve_step_metrics(stepId)
|
|
+ await client.steps.metrics.retrieve(stepId)
|
|
|
|
// Batch messages
|
|
- await client.messages.list_batch_messages(batchId)
|
|
+ await client.batches.messages.list(batchId)
|
|
|
|
// Multi-agent groups
|
|
- agent.multi_agent_group
|
|
+ agent.managed_group
|
|
```
|
|
```python Python
|
|
# Agent updates
|
|
- client.agents.modify(agent_id, **updates)
|
|
+ client.agents.update(agent_id, **updates)
|
|
|
|
// Message operations
|
|
- client.agents.summarize_agent_conversation(agent_id)
|
|
+ client.agents.messages.compact(agent_id)
|
|
|
|
- client.agents.cancel_agent_run(agent_id)
|
|
+ client.agents.messages.cancel(agent_id)
|
|
|
|
// Export/Import
|
|
- client.agents.export_agent_serialized(agent_id)
|
|
+ client.agents.export_file(agent_id)
|
|
|
|
- client.agents.import_agent_serialized(file)
|
|
+ client.agents.import_file(file)
|
|
|
|
// Folder operations
|
|
- client.folders.get_agents_for_folder(folder_id)
|
|
+ client.folders.agents.list(folder_id)
|
|
|
|
// Provider operations
|
|
- client.providers.check_provider(provider_id)
|
|
+ client.providers.check(provider_id)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 3. Deprecations
|
|
|
|
Several endpoints and fields are now deprecated:
|
|
|
|
**Deprecated endpoints:**
|
|
- `client.agents.search()` - use `client.agents.list()` with filters
|
|
- `client.messages.search()` - use `client.agents.messages.list()` with filters
|
|
- `client.runs.list_active()` - use `client.runs.list(active=True)`
|
|
- `client.jobs.list_active()` - use `client.jobs.list(active=True)`
|
|
- `client.folders.get_by_name()` - use `client.folders.list(name="...")`
|
|
- **MCP routes under `/tools/mcp/servers`** - replaced with new `/mcp-servers` endpoints
|
|
- All old MCP methods moved from `client.tools.mcp.servers` to `client.mcp_servers`
|
|
- Now use server IDs and tool IDs instead of names
|
|
- Sources-related routes - replaced with folders
|
|
- Passages routes - replaced with archives
|
|
- Legacy agent architecture routes
|
|
- All `/count` endpoints
|
|
|
|
**Deprecated fields:**
|
|
- `agent.memory` - use `agent.blocks`
|
|
- `step.messages` - use `client.steps.messages.list(step_id)`
|
|
- `agent.identity_ids` - replaced with `agent.identities` (full objects)
|
|
- `agent.multi_agent_group` - renamed to `agent.managed_group`
|
|
- `use_assistant_message` parameter - no longer needed
|
|
- `tool_exec_environment_variables` - renamed to `secrets`
|
|
|
|
**Deprecated on agent/block objects:**
|
|
- Template-related fields: `is_template`, `base_template_id`, `deployment_id`
|
|
- `entity_id`, `preserve_on_migration`, `hidden`
|
|
- `name` on blocks (use `label`)
|
|
|
|
### 4. Property Names (camelCase → snake_case)
|
|
|
|
All API properties now use `snake_case`:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Agent properties
|
|
- agent.llmConfig
|
|
+ agent.llm_config
|
|
|
|
- agent.contextWindowLimit
|
|
+ agent.context_window_limit
|
|
|
|
- agent.blockIds
|
|
+ agent.block_ids
|
|
|
|
- agent.includeBaseTools
|
|
+ agent.include_base_tools
|
|
|
|
- agent.includeBaseToolRules
|
|
+ agent.include_base_tool_rules
|
|
|
|
- agent.initialMessageSequence
|
|
+ agent.initial_message_sequence
|
|
|
|
// Message properties
|
|
- message.messageType
|
|
+ message.message_type
|
|
|
|
- message.toolCallId
|
|
+ message.tool_call_id
|
|
|
|
- message.toolReturn
|
|
+ message.tool_return
|
|
|
|
- message.toolCall
|
|
+ message.tool_calls // Also changed to array!
|
|
|
|
// API parameters
|
|
- streamTokens: true
|
|
+ stream_tokens: true
|
|
|
|
- approvalRequestId: id
|
|
+ approval_request_id: id
|
|
```
|
|
```python Python
|
|
# Agent properties
|
|
- agent.llm_config # Already snake_case
|
|
+ agent.llm_config # No change needed
|
|
|
|
- agent.context_window_limit
|
|
+ agent.context_window_limit # No change needed
|
|
|
|
# Python SDK was already using snake_case
|
|
# Most changes affect TypeScript/JavaScript only
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 2. Agent Type Specification
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old
|
|
- agentType: Letta.AgentType.LettaV1Agent
|
|
|
|
// New
|
|
+ agent_type: "letta_v1_agent" as AgentType
|
|
```
|
|
```python Python
|
|
# Old
|
|
- agent_type=AgentType.LETTA_V1_AGENT
|
|
|
|
# New
|
|
+ agent_type="letta_v1_agent"
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 3. Method Renames
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Agent updates
|
|
- await client.agents.modify(agentId, { model, llmConfig })
|
|
+ await client.agents.update(agentId, { model, llm_config })
|
|
|
|
// Message streaming
|
|
- client.agents.messages.createStream(agentId, { messages, streamTokens })
|
|
+ client.agents.messages.stream(agentId, { messages, stream_tokens })
|
|
```
|
|
```python Python
|
|
# Agent updates
|
|
- client.agents.modify(agent_id, model=model, llm_config=config)
|
|
+ client.agents.update(agent_id, model=model, llm_config=config)
|
|
|
|
# Message streaming
|
|
- client.agents.messages.create_stream(agent_id, messages=messages)
|
|
+ client.agents.messages.stream(agent_id, messages=messages)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 4. Message Roles and Stop Reasons
|
|
|
|
Enums replaced with string literals:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Message roles
|
|
- role: Letta.MessageCreateRole.User
|
|
+ role: "user"
|
|
|
|
// Stop reasons
|
|
- if (stopReason === Letta.StopReasonType.EndTurn)
|
|
+ if (stopReason === "end_turn")
|
|
|
|
- if (stopReason === Letta.StopReasonType.RequiresApproval)
|
|
+ if (stopReason === "requires_approval")
|
|
```
|
|
```python Python
|
|
# Message roles
|
|
- role=MessageRole.USER
|
|
+ role="user"
|
|
|
|
# Stop reasons
|
|
- if stop_reason == StopReasonType.END_TURN:
|
|
+ if stop_reason == "end_turn":
|
|
|
|
- if stop_reason == StopReasonType.REQUIRES_APPROVAL:
|
|
+ if stop_reason == "requires_approval":
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 5. Tool Calls Structure
|
|
|
|
Tool calls changed from single object to array:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old - single tool_call
|
|
- if (message.messageType === "approval_request_message") {
|
|
- const toolCall = message.toolCall;
|
|
- const id = toolCall.toolCallId;
|
|
- const name = toolCall.name;
|
|
- }
|
|
|
|
// New - tool_calls array
|
|
+ if (message.message_type === "approval_request_message") {
|
|
+ const toolCalls = message.tool_calls || [];
|
|
+ if (toolCalls.length > 0) {
|
|
+ const toolCall = toolCalls[0];
|
|
+ const id = toolCall.tool_call_id;
|
|
+ const name = toolCall.name;
|
|
+ }
|
|
+ }
|
|
```
|
|
```python Python
|
|
# Old - single tool_call
|
|
- if message.message_type == "approval_request_message":
|
|
- tool_call = message.tool_call
|
|
- id = tool_call.tool_call_id
|
|
- name = tool_call.name
|
|
|
|
# New - tool_calls array
|
|
+ if message.message_type == "approval_request_message":
|
|
+ tool_calls = message.tool_calls or []
|
|
+ if len(tool_calls) > 0:
|
|
+ tool_call = tool_calls[0]
|
|
+ id = tool_call.tool_call_id
|
|
+ name = tool_call.name
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 6. Pagination
|
|
|
|
List methods now return page objects:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old
|
|
- const messages = await client.agents.messages.list(agentId);
|
|
|
|
// New
|
|
+ const messagesPage = await client.agents.messages.list(agentId);
|
|
+ const messages = messagesPage.items;
|
|
```
|
|
```python Python
|
|
# Old
|
|
- messages = client.agents.messages.list(agent_id=agent_id)
|
|
|
|
# New
|
|
+ messages_page = client.agents.messages.list(agent_id=agent_id)
|
|
+ messages = messages_page.items
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 7. Date Handling
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old
|
|
- date: new Date()
|
|
|
|
// New
|
|
+ date: new Date().toISOString()
|
|
```
|
|
```python Python
|
|
# Python handles this automatically
|
|
from datetime import datetime
|
|
date = datetime.now() # Works in both versions
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 8. Archive Management (New APIs)
|
|
|
|
New endpoints for managing archival memory:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Create archive
|
|
const archive = await client.archives.create({
|
|
name: "my-archive",
|
|
description: "Project knowledge base"
|
|
});
|
|
|
|
// List archives
|
|
const archives = await client.archives.list();
|
|
|
|
// Get archive by ID
|
|
const archive = await client.archives.retrieve(archiveId);
|
|
|
|
// Update archive
|
|
await client.archives.update(archiveId, { name: "updated-name" });
|
|
|
|
// Delete archive
|
|
await client.archives.delete(archiveId);
|
|
|
|
// Attach archive to agent
|
|
await client.agents.archives.attach(agentId, archiveId);
|
|
|
|
// Detach archive from agent
|
|
await client.agents.archives.detach(agentId, archiveId);
|
|
|
|
// List agents using an archive
|
|
const agents = await client.archives.agents.list(archiveId);
|
|
|
|
// Manage memories in archive
|
|
await client.archives.memories.create(archiveId, { text: "Important fact" });
|
|
await client.archives.memories.update(archiveId, memoryId, { text: "Updated fact" });
|
|
await client.archives.memories.delete(archiveId, memoryId);
|
|
```
|
|
```python Python
|
|
# Create archive
|
|
archive = client.archives.create(
|
|
name="my-archive",
|
|
description="Project knowledge base"
|
|
)
|
|
|
|
# Attach/detach
|
|
client.agents.archives.attach(agent_id, archive_id)
|
|
client.agents.archives.detach(agent_id, archive_id)
|
|
|
|
# Manage memories
|
|
client.archives.memories.create(archive_id, text="Important fact")
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 9. Identity and Block Management
|
|
|
|
New attach/detach patterns for identities and blocks:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Attach identity to agent
|
|
await client.agents.identities.attach(agentId, identityId);
|
|
|
|
// Detach identity from agent
|
|
await client.agents.identities.detach(agentId, identityId);
|
|
|
|
// Attach identity to block
|
|
await client.blocks.identities.attach(blockId, identityId);
|
|
|
|
// Detach identity from block
|
|
await client.blocks.identities.detach(blockId, identityId);
|
|
|
|
// Agent now returns full identity objects
|
|
const agent = await client.agents.retrieve(agentId);
|
|
// Old: agent.identity_ids = ["id1", "id2"]
|
|
// New: agent.identities = [{ id: "id1", name: "Alice", ... }, ...]
|
|
```
|
|
```python Python
|
|
# Attach/detach identities
|
|
client.agents.identities.attach(agent_id, identity_id)
|
|
client.agents.identities.detach(agent_id, identity_id)
|
|
|
|
# Full identity objects
|
|
agent = client.agents.retrieve(agent_id)
|
|
for identity in agent.identities:
|
|
print(identity.name)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 10. Agent Configuration Updates
|
|
|
|
New parameters available for agent creation and updates:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Temperature, top_p, reasoning_effort now available at top level
|
|
const agent = await client.agents.create({
|
|
model: "openai/gpt-4",
|
|
temperature: 0.7,
|
|
top_p: 0.9,
|
|
reasoning_effort: "medium",
|
|
max_tokens: 4096,
|
|
context_window_limit: 128000
|
|
});
|
|
|
|
// Update agent configuration
|
|
await client.agents.update(agentId, {
|
|
temperature: 0.5,
|
|
context_window_limit: 64000
|
|
});
|
|
```
|
|
```python Python
|
|
# Create with configuration
|
|
agent = client.agents.create(
|
|
model="openai/gpt-4",
|
|
temperature=0.7,
|
|
top_p=0.9,
|
|
reasoning_effort="medium",
|
|
max_tokens=4096,
|
|
context_window_limit=128000
|
|
)
|
|
|
|
# Update configuration
|
|
client.agents.update(
|
|
agent_id,
|
|
temperature=0.5
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 11. Message Input Shorthand
|
|
|
|
Simplified syntax for sending simple user messages:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old - verbose
|
|
const response = await client.agents.messages.create(agentId, {
|
|
messages: [{
|
|
role: "user",
|
|
content: "Hello!"
|
|
}]
|
|
});
|
|
|
|
// New - shorthand available
|
|
const response = await client.agents.messages.create(agentId, {
|
|
input: "Hello!" // Automatically creates user message
|
|
});
|
|
|
|
// Both forms still supported
|
|
```
|
|
```python Python
|
|
# Old
|
|
response = client.agents.messages.create(
|
|
agent_id,
|
|
messages=[{"role": "user", "content": "Hello!"}]
|
|
)
|
|
|
|
# New shorthand
|
|
response = client.agents.messages.create(
|
|
agent_id,
|
|
input="Hello!"
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 12. Attach/Detach Return Values
|
|
|
|
All attach/detach endpoints now return `None` instead of agent/object state:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old - returned updated agent
|
|
const updatedAgent = await client.agents.tools.attach(agentId, toolId);
|
|
|
|
// New - returns void/None
|
|
await client.agents.tools.attach(agentId, toolId);
|
|
// Fetch agent separately if needed
|
|
const agent = await client.agents.retrieve(agentId);
|
|
```
|
|
```python Python
|
|
# Old
|
|
updated_agent = client.agents.tools.attach(agent_id, tool_id)
|
|
|
|
# New
|
|
client.agents.tools.attach(agent_id, tool_id)
|
|
agent = client.agents.retrieve(agent_id)
|
|
```
|
|
</CodeGroup>
|
|
|
|
**Affected methods:**
|
|
- `agents.tools.attach/detach`
|
|
- `agents.blocks.attach/detach`
|
|
- `agents.folders.attach/detach`
|
|
- `agents.archives.attach/detach`
|
|
- `agents.identities.attach/detach`
|
|
- `blocks.identities.attach/detach`
|
|
|
|
### 13. Agent Import/Export Changes
|
|
|
|
Import endpoint now supports name overriding:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old - append_copy_suffix parameter
|
|
const agent = await client.agents.import(file, {
|
|
append_copy_suffix: true // Deprecated
|
|
});
|
|
|
|
// New - override_name parameter
|
|
const agent = await client.agents.importFile(file, {
|
|
override_name: "my-imported-agent" // Optional, exact name to use
|
|
});
|
|
```
|
|
```python Python
|
|
# Old
|
|
agent = client.agents.import_agent(
|
|
file,
|
|
append_copy_suffix=True
|
|
)
|
|
|
|
# New
|
|
agent = client.agents.import_file(
|
|
file,
|
|
override_name="my-imported-agent"
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 14. Query Parameter to Request Body Changes
|
|
|
|
Several endpoints moved from query parameters to request body:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Tool approval settings (was query params, now request body)
|
|
await client.agents.tools.update_approval(agentId, toolName, {
|
|
require_approval: true
|
|
});
|
|
|
|
// Reset messages (was query param, now request body)
|
|
await client.agents.messages.reset(agentId, {
|
|
add_default_initial_messages: false
|
|
});
|
|
|
|
// Steps feedback (was query params, now request body)
|
|
await client.steps.feedback.create(stepId, {
|
|
rating: "positive",
|
|
tags: ["helpful", "accurate"]
|
|
});
|
|
```
|
|
```python Python
|
|
# Tool approval
|
|
client.agents.tools.update_approval(
|
|
agent_id,
|
|
tool_name,
|
|
require_approval=True
|
|
)
|
|
|
|
# Reset messages
|
|
client.agents.messages.reset(
|
|
agent_id,
|
|
add_default_initial_messages=False
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 15. Tags Endpoint
|
|
|
|
Tags list endpoint now uses `name` parameter instead of `query_text`:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Old
|
|
const tags = await client.tags.list({ query_text: "important" });
|
|
|
|
// New
|
|
const tags = await client.tags.list({ name: "important" });
|
|
```
|
|
```python Python
|
|
# Old
|
|
tags = client.tags.list(query_text="important")
|
|
|
|
# New
|
|
tags = client.tags.list(name="important")
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 16. Project ID Handling
|
|
|
|
Project ID is now passed in the client constructor or headers:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Pass in constructor
|
|
const client = new Letta({
|
|
apiKey: process.env.LETTA_API_KEY,
|
|
projectId: "proj_123"
|
|
});
|
|
|
|
// No longer in URL paths
|
|
- await client.templates.agents.create("proj_123", templateVersion, data)
|
|
+ await client.templates.agents.create(templateVersion, data)
|
|
```
|
|
```python Python
|
|
# Pass in constructor
|
|
client = Letta(
|
|
api_key=os.environ["LETTA_API_KEY"],
|
|
project_id="proj_123"
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### 17. MCP (Model Context Protocol) Server Management
|
|
|
|
MCP routes have been completely restructured with new endpoints under `/mcp-servers`:
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// OLD ROUTES (under /tools/mcp/servers - DEPRECATED)
|
|
// Using server names and tool names
|
|
|
|
// List MCP servers
|
|
- const servers = await client.tools.mcp.servers.list();
|
|
|
|
// Add MCP server
|
|
- await client.tools.mcp.servers.create(serverConfig);
|
|
|
|
// Update MCP server by name
|
|
- await client.tools.mcp.servers.update(serverName, updateConfig);
|
|
|
|
// Delete MCP server by name
|
|
- await client.tools.mcp.servers.delete(serverName);
|
|
|
|
// List tools from a server by name
|
|
- const tools = await client.tools.mcp.servers.tools.list(serverName);
|
|
|
|
// Add individual tool by name
|
|
- await client.tools.mcp.servers.tools.add(serverName, toolName);
|
|
|
|
// Resync tools
|
|
- await client.tools.mcp.servers.resync(serverName);
|
|
|
|
// Execute tool by names
|
|
- await client.tools.mcp.servers.tools.execute(serverName, toolName, { args });
|
|
|
|
// Connect to server (for OAuth)
|
|
- await client.tools.mcp.servers.connect(serverConfig);
|
|
|
|
// NEW ROUTES (under /mcp-servers)
|
|
// Using server IDs and tool IDs
|
|
|
|
// List MCP servers (returns array of server objects with IDs)
|
|
+ const servers = await client.mcp_servers.list();
|
|
|
|
// Create MCP server (automatically syncs tools)
|
|
+ const server = await client.mcp_servers.create(serverConfig);
|
|
+ // Returns: { id: "mcp_server_123", name: "...", ... }
|
|
|
|
// Get MCP server by ID
|
|
+ const server = await client.mcp_servers.retrieve(serverId);
|
|
|
|
// Update MCP server by ID
|
|
+ await client.mcp_servers.update(serverId, updateConfig);
|
|
|
|
// Delete MCP server by ID
|
|
+ await client.mcp_servers.delete(serverId);
|
|
|
|
// List tools from a server by ID
|
|
+ const tools = await client.mcp_servers.tools.list(serverId);
|
|
|
|
// Get specific tool by ID
|
|
+ const tool = await client.mcp_servers.tools.retrieve(serverId, toolId);
|
|
|
|
// Run/execute tool by ID
|
|
+ const result = await client.mcp_servers.tools.run(serverId, toolId, {
|
|
+ args: { key: "value" }
|
|
+ });
|
|
|
|
// Refresh tools (replaces resync)
|
|
+ await client.mcp_servers.refresh(serverId);
|
|
|
|
// Connect to server (for OAuth) - now uses server ID
|
|
+ await client.mcp_servers.connect(serverId);
|
|
```
|
|
```python Python
|
|
# OLD ROUTES (DEPRECATED)
|
|
- servers = client.tools.mcp.servers.list()
|
|
- client.tools.mcp.servers.create(server_config)
|
|
- client.tools.mcp.servers.update(server_name, update_config)
|
|
- client.tools.mcp.servers.delete(server_name)
|
|
- tools = client.tools.mcp.servers.tools.list(server_name)
|
|
- client.tools.mcp.servers.tools.add(server_name, tool_name)
|
|
- client.tools.mcp.servers.resync(server_name)
|
|
- client.tools.mcp.servers.tools.execute(server_name, tool_name, args=args)
|
|
|
|
# NEW ROUTES
|
|
+ servers = client.mcp_servers.list()
|
|
+ server = client.mcp_servers.create(server_config)
|
|
+ server = client.mcp_servers.retrieve(server_id)
|
|
+ client.mcp_servers.update(server_id, update_config)
|
|
+ client.mcp_servers.delete(server_id)
|
|
+ tools = client.mcp_servers.tools.list(server_id)
|
|
+ tool = client.mcp_servers.tools.retrieve(server_id, tool_id)
|
|
+ result = client.mcp_servers.tools.run(server_id, tool_id, args={"key": "value"})
|
|
+ client.mcp_servers.refresh(server_id)
|
|
+ client.mcp_servers.connect(server_id)
|
|
```
|
|
</CodeGroup>
|
|
|
|
**Key Changes:**
|
|
- **Namespace**: Moved from `client.tools.mcp.servers` to `client.mcp_servers`
|
|
- **Identification**: Use server IDs and tool IDs instead of names
|
|
- Old: `serverName` (string) → New: `serverId` (ID string like `"mcp_server_123"`)
|
|
- Old: `toolName` (string) → New: `toolId` (ID string like `"tool_456"`)
|
|
- **Tool Management**: Tools are now automatically synced when creating a server
|
|
- No longer need to manually "add" individual tools
|
|
- Use `refresh()` to resync tools (replaces `resync()`)
|
|
- **Tool Execution**: Method renamed from `execute()` to `run()`
|
|
- **Server Retrieval**: New `retrieve()` method to get individual server by ID
|
|
- **Tool Retrieval**: New `retrieve()` method to get individual tool by ID
|
|
|
|
**Migration Example:**
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Before: Using names
|
|
const servers = await client.tools.mcp.servers.list();
|
|
const myServer = servers.find(s => s.name === "my-server");
|
|
const tools = await client.tools.mcp.servers.tools.list("my-server");
|
|
const myTool = tools.find(t => t.name === "my-tool");
|
|
await client.tools.mcp.servers.tools.execute("my-server", "my-tool", {
|
|
args: { query: "hello" }
|
|
});
|
|
|
|
// After: Using IDs
|
|
const servers = await client.mcp_servers.list();
|
|
const myServer = servers.find(s => s.name === "my-server");
|
|
const serverId = myServer.id; // Get ID from server object
|
|
const tools = await client.mcp_servers.tools.list(serverId);
|
|
const myTool = tools.find(t => t.name === "my-tool");
|
|
const toolId = myTool.id; // Get ID from tool object
|
|
await client.mcp_servers.tools.run(serverId, toolId, {
|
|
args: { query: "hello" }
|
|
});
|
|
```
|
|
```python Python
|
|
# Before
|
|
servers = client.tools.mcp.servers.list()
|
|
my_server = next(s for s in servers if s.name == "my-server")
|
|
tools = client.tools.mcp.servers.tools.list("my-server")
|
|
my_tool = next(t for t in tools if t.name == "my-tool")
|
|
client.tools.mcp.servers.tools.execute(
|
|
"my-server",
|
|
"my-tool",
|
|
args={"query": "hello"}
|
|
)
|
|
|
|
# After
|
|
servers = client.mcp_servers.list()
|
|
my_server = next(s for s in servers if s.name == "my-server")
|
|
server_id = my_server.id
|
|
tools = client.mcp_servers.tools.list(server_id)
|
|
my_tool = next(t for t in tools if t.name == "my-tool")
|
|
tool_id = my_tool.id
|
|
client.mcp_servers.tools.run(
|
|
server_id,
|
|
tool_id,
|
|
args={"query": "hello"}
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
**Notes:**
|
|
- MCP servers and tools now have persistent IDs in the database
|
|
- Server names are no longer unique identifiers - use IDs instead
|
|
- Tool schemas are automatically kept in sync via the `refresh()` endpoint
|
|
- The old routes under `/tools/mcp/servers` are deprecated and will be removed
|
|
|
|
## Migration Examples
|
|
|
|
### Complete Agent Creation
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Before
|
|
const agent = await client.agents.create({
|
|
agentType: Letta.AgentType.LettaV1Agent,
|
|
model: "openai/gpt-4",
|
|
contextWindowLimit: 200_000,
|
|
blockIds: ["block-1", "block-2"],
|
|
includeBaseTools: false,
|
|
includeBaseToolRules: false,
|
|
initialMessageSequence: [],
|
|
});
|
|
|
|
// After
|
|
const agent = await client.agents.create({
|
|
agent_type: "letta_v1_agent" as AgentType,
|
|
model: "openai/gpt-4",
|
|
context_window_limit: 200_000,
|
|
block_ids: ["block-1", "block-2"],
|
|
include_base_tools: false,
|
|
include_base_tool_rules: false,
|
|
initial_message_sequence: [],
|
|
});
|
|
```
|
|
```python Python
|
|
# Before
|
|
agent = client.agents.create(
|
|
agent_type=AgentType.LETTA_V1_AGENT,
|
|
model="openai/gpt-4",
|
|
context_window_limit=200_000,
|
|
block_ids=["block-1", "block-2"],
|
|
include_base_tools=False,
|
|
include_base_tool_rules=False,
|
|
initial_message_sequence=[],
|
|
)
|
|
|
|
# After
|
|
agent = client.agents.create(
|
|
agent_type="letta_v1_agent",
|
|
model="openai/gpt-4",
|
|
context_window_limit=200_000,
|
|
block_ids=["block-1", "block-2"],
|
|
include_base_tools=False,
|
|
include_base_tool_rules=False,
|
|
initial_message_sequence=[],
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Streaming Messages
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Before
|
|
const stream = await client.agents.messages.createStream(agentId, {
|
|
messages: [{
|
|
role: Letta.MessageCreateRole.User,
|
|
content: "Hello"
|
|
}],
|
|
streamTokens: true,
|
|
});
|
|
|
|
// After
|
|
const stream = await client.agents.messages.stream(agentId, {
|
|
messages: [{
|
|
role: "user",
|
|
content: "Hello"
|
|
}],
|
|
stream_tokens: true,
|
|
});
|
|
```
|
|
```python Python
|
|
# Before
|
|
stream = client.agents.messages.create_stream(
|
|
agent_id=agent_id,
|
|
messages=[{"role": "user", "content": "Hello"}],
|
|
stream_tokens=True,
|
|
)
|
|
|
|
# After
|
|
stream = client.agents.messages.stream(
|
|
agent_id=agent_id,
|
|
messages=[{"role": "user", "content": "Hello"}],
|
|
stream_tokens=True,
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Handling Approvals
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Before
|
|
if (message.messageType === "approval_request_message") {
|
|
const toolCall = message.toolCall;
|
|
await client.agents.messages.create(agentId, {
|
|
messages: [{
|
|
type: "approval",
|
|
approvalRequestId: toolCall.toolCallId,
|
|
approve: true,
|
|
}],
|
|
});
|
|
}
|
|
|
|
// After
|
|
if (message.message_type === "approval_request_message") {
|
|
const toolCalls = message.tool_calls || [];
|
|
if (toolCalls.length > 0) {
|
|
const toolCall = toolCalls[0];
|
|
await client.agents.messages.create(agentId, {
|
|
messages: [{
|
|
type: "approval",
|
|
approval_request_id: toolCall.tool_call_id,
|
|
approve: true,
|
|
}],
|
|
});
|
|
}
|
|
}
|
|
```
|
|
```python Python
|
|
# Before
|
|
if message.message_type == "approval_request_message":
|
|
tool_call = message.tool_call
|
|
client.agents.messages.create(
|
|
agent_id=agent_id,
|
|
messages=[{
|
|
"type": "approval",
|
|
"approval_request_id": tool_call.tool_call_id,
|
|
"approve": True,
|
|
}],
|
|
)
|
|
|
|
# After
|
|
if message.message_type == "approval_request_message":
|
|
tool_calls = message.tool_calls or []
|
|
if len(tool_calls) > 0:
|
|
tool_call = tool_calls[0]
|
|
client.agents.messages.create(
|
|
agent_id=agent_id,
|
|
messages=[{
|
|
"type": "approval",
|
|
"approval_request_id": tool_call.tool_call_id,
|
|
"approve": True,
|
|
}],
|
|
)
|
|
```
|
|
</CodeGroup>
|
|
|
|
### Updating Agent Configuration
|
|
|
|
<CodeGroup>
|
|
```typescript TypeScript
|
|
// Before
|
|
await client.agents.modify(agentId, {
|
|
model: "openai/gpt-4",
|
|
llmConfig: { temperature: 0.7 }
|
|
});
|
|
const agent = await client.agents.retrieve(agentId);
|
|
const config = agent.llmConfig;
|
|
|
|
// After
|
|
await client.agents.update(agentId, {
|
|
model: "openai/gpt-4",
|
|
llm_config: { temperature: 0.7 }
|
|
});
|
|
const agent = await client.agents.retrieve(agentId);
|
|
const config = agent.llm_config;
|
|
```
|
|
```python Python
|
|
# Before
|
|
client.agents.modify(
|
|
agent_id=agent_id,
|
|
model="openai/gpt-4",
|
|
llm_config={"temperature": 0.7}
|
|
)
|
|
agent = client.agents.retrieve(agent_id=agent_id)
|
|
config = agent.llm_config
|
|
|
|
# After
|
|
client.agents.update(
|
|
agent_id=agent_id,
|
|
model="openai/gpt-4",
|
|
llm_config={"temperature": 0.7}
|
|
)
|
|
agent = client.agents.retrieve(agent_id=agent_id)
|
|
config = agent.llm_config
|
|
```
|
|
</CodeGroup>
|
|
|
|
## Migration Checklist
|
|
|
|
Use this checklist to ensure a complete migration:
|
|
|
|
**Core SDK Changes:**
|
|
- [ ] Update package version to `1.0.0-alpha.10` or later
|
|
- [ ] Update all imports (client and types)
|
|
- [ ] Replace `LettaClient` with `Letta`
|
|
- [ ] Update client constructor params: `token` → `apiKey`, `baseUrl` → `baseURL`
|
|
- [ ] Add `projectId` to client constructor if using multi-project setup
|
|
- [ ] Convert all property names from `camelCase` to `snake_case`
|
|
- [ ] Replace enum references with string literals
|
|
- [ ] Convert `Date` objects to ISO strings where required
|
|
- [ ] Update type annotations to use new import paths
|
|
|
|
**Method Renames:**
|
|
- [ ] Update `modify()` calls to `update()`
|
|
- [ ] Update `createStream()` calls to `stream()`
|
|
- [ ] Rename `summarize_agent_conversation()` → `messages.compact()`
|
|
- [ ] Rename `cancel_agent_run()` → `messages.cancel()`
|
|
- [ ] Rename `preview_raw_payload()` → `messages.preview()`
|
|
- [ ] Rename `list_agent_files()` → `files.list()`
|
|
- [ ] Rename `export_agent_serialized()` → `export_file()`
|
|
- [ ] Rename `import_agent_serialized()` → `import_file()`
|
|
- [ ] Rename folder/provider method names (see section 2)
|
|
- [ ] Update telemetry routes to use `steps.trace()`
|
|
|
|
**Pagination:**
|
|
- [ ] Update all list methods to access `.items` property
|
|
- [ ] Replace `sort_by` with `order_by` in `agents.list()`
|
|
- [ ] Replace `ascending` with `order` parameter
|
|
- [ ] Update pagination parameters: `before`, `after`, `limit`, `order`
|
|
- [ ] Handle cursor-based pagination for all list endpoints
|
|
|
|
**Message Handling:**
|
|
- [ ] Handle `tool_calls` as an array instead of single object
|
|
- [ ] Update `identity_ids` references to use `identities` (full objects)
|
|
- [ ] Replace `agent.memory` with `agent.blocks`
|
|
- [ ] Update `step.messages` to use `steps.messages.list()`
|
|
- [ ] Consider using new `input` shorthand for simple messages
|
|
|
|
**Deprecations:**
|
|
- [ ] Remove usage of deprecated search endpoints
|
|
- [ ] Replace `list_active()` with `list(active=True)`
|
|
- [ ] Remove `use_assistant_message` parameter
|
|
- [ ] Replace `tool_exec_environment_variables` with `secrets`
|
|
- [ ] Remove template-related fields from agent/block objects
|
|
- [ ] Replace sources endpoints with folders
|
|
- [ ] Replace passages endpoints with archives
|
|
|
|
**New Features:**
|
|
- [ ] Update attach/detach methods (now return `None`)
|
|
- [ ] Use new archive management APIs if needed
|
|
- [ ] Update agent import to use `override_name` instead of `append_copy_suffix`
|
|
- [ ] Move query parameters to request body for affected endpoints
|
|
- [ ] Use new agent configuration parameters (`temperature`, `top_p`, etc.)
|
|
|
|
**MCP (Model Context Protocol) Changes:**
|
|
- [ ] Migrate from `client.tools.mcp.servers` to `client.mcp_servers`
|
|
- [ ] Update MCP server references to use IDs instead of names
|
|
- [ ] Update MCP tool references to use IDs instead of names
|
|
- [ ] Remove manual tool "add" operations (tools auto-sync on server create)
|
|
- [ ] Replace `resync()` calls with `refresh()`
|
|
- [ ] Replace `execute()` calls with `run()`
|
|
- [ ] Add server/tool ID lookup logic if using names
|
|
- [ ] Update OAuth connection flow to use server IDs
|
|
|
|
**Testing:**
|
|
- [ ] Test all agent operations (create, update, message)
|
|
- [ ] Test streaming and approval flows
|
|
- [ ] Verify memory block operations still work
|
|
- [ ] Test pagination on list endpoints
|
|
- [ ] Test archive management if used
|
|
- [ ] Verify identity/block attach/detach operations
|
|
- [ ] Test agent import/export
|
|
|
|
## Automated Migration Tools
|
|
|
|
### Find and Replace Script
|
|
|
|
Use this script to help automate common replacements:
|
|
|
|
<CodeGroup>
|
|
```bash Shell (TypeScript projects)
|
|
# Install dependencies
|
|
npm install -g jscodeshift
|
|
|
|
# Run find-and-replace (adjust paths as needed)
|
|
find src -name "*.ts" -o -name "*.tsx" | xargs sed -i '' \
|
|
-e 's/LettaClient/Letta/g' \
|
|
-e 's/\.modify(/.update(/g' \
|
|
-e 's/\.createStream(/.stream(/g' \
|
|
-e 's/\.messageType/.message_type/g' \
|
|
-e 's/\.toolCall/.tool_calls/g' \
|
|
-e 's/\.toolCallId/.tool_call_id/g' \
|
|
-e 's/\.toolReturn/.tool_return/g' \
|
|
-e 's/llmConfig/llm_config/g' \
|
|
-e 's/streamTokens/stream_tokens/g' \
|
|
-e 's/\.tools\.mcp\.servers/\.mcp_servers/g' \
|
|
-e 's/\.resync(/\.refresh(/g'
|
|
|
|
# Note: MCP server/tool name -> ID migration requires manual intervention
|
|
# as you need to fetch IDs from the API
|
|
```
|
|
```python Python (migration helper)
|
|
import re
|
|
from pathlib import Path
|
|
|
|
def migrate_file(filepath: Path):
|
|
"""Apply SDK v1.0 migration patterns to a Python file"""
|
|
content = filepath.read_text()
|
|
|
|
# Import updates
|
|
content = re.sub(
|
|
r'from letta_client import (\w+)',
|
|
r'from letta import \1',
|
|
content
|
|
)
|
|
|
|
# Method renames
|
|
content = content.replace('.modify(', '.update(')
|
|
content = content.replace('.create_stream(', '.stream(')
|
|
|
|
# MCP namespace changes
|
|
content = content.replace('.tools.mcp.servers', '.mcp_servers')
|
|
content = content.replace('.resync(', '.refresh(')
|
|
|
|
# Already using snake_case in Python, but fix any camelCase
|
|
content = re.sub(r'messageType', 'message_type', content)
|
|
content = re.sub(r'toolCall([^_])', r'tool_calls\1', content)
|
|
|
|
filepath.write_text(content)
|
|
print(f"✓ Migrated {filepath}")
|
|
|
|
# Usage
|
|
for py_file in Path('src').rglob('*.py'):
|
|
migrate_file(py_file)
|
|
```
|
|
</CodeGroup>
|
|
|
|
<Warning>
|
|
**Always review automated changes!** These scripts help with common patterns but cannot handle all edge cases. Test thoroughly after migration.
|
|
</Warning>
|
|
|
|
## Troubleshooting
|
|
|
|
### "Property 'llmConfig' does not exist" (TypeScript)
|
|
|
|
**Cause:** Property renamed to `llm_config`
|
|
|
|
**Fix:** Update all references to use snake_case
|
|
|
|
```typescript
|
|
- agent.llmConfig
|
|
+ agent.llm_config
|
|
```
|
|
|
|
### "Cannot read property 'toolCallId' of undefined"
|
|
|
|
**Cause:** `tool_call` changed to `tool_calls` (array)
|
|
|
|
**Fix:** Access the first element of the array
|
|
|
|
```typescript
|
|
- const id = message.toolCall.toolCallId;
|
|
+ const toolCalls = message.tool_calls || [];
|
|
+ const id = toolCalls[0]?.tool_call_id;
|
|
```
|
|
|
|
### "items is not iterable"
|
|
|
|
**Cause:** Trying to iterate over page object instead of items array
|
|
|
|
**Fix:** Access the `.items` property first
|
|
|
|
```typescript
|
|
- for (const message of messages) {
|
|
+ const messagesPage = await client.agents.messages.list(agentId);
|
|
+ for (const message of messagesPage.items) {
|
|
```
|
|
|
|
### "Cannot find module '@letta-ai/letta-client/resources/...'"
|
|
|
|
**Cause:** Types moved to subpath exports
|
|
|
|
**Fix:** Update imports to use new subpaths
|
|
|
|
```typescript
|
|
- import { Letta } from "@letta-ai/letta-client";
|
|
+ import type { Block } from "@letta-ai/letta-client/resources/agents/agents";
|
|
```
|
|
|
|
### "Method 'modify' does not exist"
|
|
|
|
**Cause:** Method renamed to `update`
|
|
|
|
**Fix:** Update all modify calls
|
|
|
|
```typescript
|
|
- await client.agents.modify(agentId, updates)
|
|
+ await client.agents.update(agentId, updates)
|
|
```
|
|
|
|
### "Cannot access property 'identity_ids'"
|
|
|
|
**Cause:** Field renamed to `identities` and now returns full objects
|
|
|
|
**Fix:** Access the `identities` array and extract IDs if needed
|
|
|
|
```typescript
|
|
- const ids = agent.identity_ids;
|
|
+ const identities = agent.identities;
|
|
+ const ids = identities.map(i => i.id);
|
|
```
|
|
|
|
### "Pagination parameters 'sort_by' or 'ascending' not recognized"
|
|
|
|
**Cause:** Pagination parameters standardized to `order_by` and `order`
|
|
|
|
**Fix:** Update parameter names
|
|
|
|
```typescript
|
|
- await client.agents.list({ sort_by: "created_at", ascending: true })
|
|
+ await client.agents.list({ order_by: "created_at", order: "asc" })
|
|
```
|
|
|
|
### "Attach/detach methods return undefined"
|
|
|
|
**Cause:** These methods now return `None`/`void` instead of updated state
|
|
|
|
**Fix:** Fetch the object separately if you need the updated state
|
|
|
|
```typescript
|
|
await client.agents.tools.attach(agentId, toolId);
|
|
const agent = await client.agents.retrieve(agentId); // Get updated state
|
|
```
|
|
|
|
### "Cannot find method 'summarize_agent_conversation'"
|
|
|
|
**Cause:** Method moved to messages subresource
|
|
|
|
**Fix:** Use the new path
|
|
|
|
```typescript
|
|
- await client.agents.summarize_agent_conversation(agentId)
|
|
+ await client.agents.messages.compact(agentId)
|
|
```
|
|
|
|
### "Query parameter 'add_default_initial_messages' not working"
|
|
|
|
**Cause:** Parameter moved from query to request body
|
|
|
|
**Fix:** Pass as request body parameter
|
|
|
|
```typescript
|
|
- await client.agents.messages.reset(agentId, { params: { add_default_initial_messages: false } })
|
|
+ await client.agents.messages.reset(agentId, { add_default_initial_messages: false })
|
|
```
|
|
|
|
### "Cannot find 'client.tools.mcp.servers'"
|
|
|
|
**Cause:** MCP routes moved to new namespace
|
|
|
|
**Fix:** Use new MCP server methods
|
|
|
|
```typescript
|
|
- await client.tools.mcp.servers.list()
|
|
+ await client.mcp_servers.list()
|
|
```
|
|
|
|
### "MCP server not found by name"
|
|
|
|
**Cause:** MCP methods now use server IDs instead of names
|
|
|
|
**Fix:** Lookup server ID from name first
|
|
|
|
```typescript
|
|
// Get server ID from name
|
|
const servers = await client.mcp_servers.list();
|
|
const myServer = servers.find(s => s.name === "my-server");
|
|
const serverId = myServer.id;
|
|
|
|
// Use ID for subsequent operations
|
|
await client.mcp_servers.tools.list(serverId);
|
|
```
|
|
|
|
### "MCP tool 'toolName' not found"
|
|
|
|
**Cause:** MCP tool execution now uses tool IDs instead of names
|
|
|
|
**Fix:** Lookup tool ID from name first
|
|
|
|
```typescript
|
|
const tools = await client.mcp_servers.tools.list(serverId);
|
|
const myTool = tools.find(t => t.name === "my-tool");
|
|
const toolId = myTool.id;
|
|
|
|
await client.mcp_servers.tools.run(serverId, toolId, { args });
|
|
```
|
|
|
|
### "Method 'execute' not found on mcp_servers.tools"
|
|
|
|
**Cause:** Method renamed from `execute()` to `run()`
|
|
|
|
**Fix:** Use the new method name
|
|
|
|
```typescript
|
|
- await client.mcp_servers.tools.execute(serverId, toolId, { args })
|
|
+ await client.mcp_servers.tools.run(serverId, toolId, { args })
|
|
```
|
|
|
|
## Additional Resources
|
|
|
|
- [Architecture Migration Guide](/guides/legacy/migration_guide) - For migrating agent architectures
|
|
- [API Reference](/api-reference) - Complete SDK documentation
|
|
- [Changelog](/api-reference/changelog) - All SDK changes
|
|
- [GitHub](https://github.com/letta-ai/letta) - Source code and issues
|
|
- [Discord](https://discord.gg/letta) - Get help from the community
|
|
|
|
## Getting Help
|
|
|
|
If you encounter issues during migration:
|
|
|
|
1. **Check the [Changelog](/api-reference/changelog)** for detailed release notes
|
|
2. **Search [GitHub Issues](https://github.com/letta-ai/letta/issues)** for known problems
|
|
3. **Ask in [Discord #dev-help](https://discord.gg/letta)** for community support
|
|
4. **Contact support@letta.com** for enterprise support
|