Files
letta-server/fern/pages/agents/filesystem.mdx
2025-09-09 09:35:12 -07:00

217 lines
6.7 KiB
Plaintext

---
title: Letta Filesystem
subtitle: Connecting agents to external documents
slug: guides/agents/filesystem
---
Letta's filesystem allow you to easily connect your agents to external files, for example: research papers, reports, medical records, or any other data in common text formats (`.pdf`, `.txt`, `.md`, `.json`, etc.).
To upload a file, you must create a folder (with a name and description) to upload files to, which can be done through the ADE or API.
```mermaid
graph TB
subgraph "Folders"
DS1[Folder 1<br/>Research Papers]
DS2[Folder 2<br/>Medical Records]
end
subgraph "Files"
F1[paper1.pdf]
F2[paper2.pdf]
F3[patient_record.txt]
F4[lab_results.json]
end
subgraph "Letta Agents"
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
DS1 --> F1
DS1 --> F2
DS2 --> F3
DS2 --> F4
A2 -.->|attached to| DS1
A2 -.->|attached to| DS2
A3 -.->|attached to| DS2
```
Once a file has been uploaded to a folder, the agent can access it using a set of **file tools**.
The file is automatically chunked and embedded to allow the agent to use semantic search to find relevant information in the file (in addition to standard text-based search).
<Tip>
If you've used [Claude Projects](https://www.anthropic.com/news/projects) before, you can think of a **folder** in Letta as a "project", except in Letta you can connect a single agent to multiple projects (in Claude Projects, a chat session can only be associated with a single project).
</Tip>
## File tools
When a folder is attached to an agent, Letta automatically attaches a set of file tools to the agent:
* `open_file`: Open a file to a specific location
* `grep_file`: Search a file using a regular expression
* `search_file`: Search a file using semantic (embedding-based) search
To detach these tools from your agent, simply detach all your folders, the file tools will be automatically removed.
## Creating a folder
### ADE
To create a folder click the "Filesystem" tab in the bottom-left of the ADE, then click the "create folder" button. When you create a folder inside the ADE, it will be automatically attached to your agent.
### API / SDK
To create a folder, you will need to specify a unique `name` as well as an `EmbeddingConfig`:
<CodeGroup>
```python title="python"
# get an available embedding_config
embedding_configs = client.embedding_models.list()
embedding_config = embedding_configs[0]
# create the folder
folder = client.folders.create(
name="my_folder",
embedding_config=embedding_config
)
```
```typescript title="node.js"
// get an available embedding_config
const embeddingConfigs = await client.embeddingModels.list()
const embeddingConfig = embeddingConfigs[0];
// create the folder
const folder = await client.folders.create({
name: "my_folder",
embeddingConfig: embeddingConfig
});
```
</CodeGroup>
Now that you've created the folder, you can start loading data into the folder.
## Uploading a file into a folder
### ADE
Click the "Filesystem" tab in the bottom-left of the ADE to view your attached folders.
To upload a file, simply drag and drop the file into the folders tab, or click the upload (+) button.
### API / SDK
Uploading a file to a folder will create an async job for processing the file, which will split the file into chunks and embed them.
<CodeGroup>
```python title="python"
# upload a file into the folder
job = client.folders.files.upload(
folder_id=folder.id,
file=open("my_file.txt", "rb")
)
# wait until the job is completed
while True:
job = client.jobs.retrieve(job.id)
if job.status == "completed":
break
elif job.status == "failed":
raise ValueError(f"Job failed: {job.metadata}")
print(f"Job status: {job.status}")
time.sleep(1)
```
```typescript title="node.js"
// upload a file into the folder
const uploadJob = await client.folders.files.upload(
createReadStream("my_file.txt"),
folder.id,
);
console.log("file uploaded")
// wait until the job is completed
while (true) {
const job = await client.jobs.retrieve(uploadJob.id);
if (job.status === "completed") {
break;
} else if (job.status === "failed") {
throw new Error(`Job failed: ${job.metadata}`);
}
console.log(`Job status: ${job.status}`);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
```
</CodeGroup>
Once the job is completed, you can list the files and the generated passages in the folder:
<CodeGroup>
```python title="python"
# list files in the folder
files = client.folders.files.list(folder_id=folder.id)
print(f"Files in folder: {files}")
# list passages in the folder
passages = client.folders.passages.list(folder_id=folder.id)
print(f"Passages in folder: {passages}")
```
```typescript title="node.js"
// list files in the folder
const files = await client.folders.files.list(folder.id);
console.log(`Files in folder: ${files}`);
// list passages in the folder
const passages = await client.folders.passages.list(folder.id);
console.log(`Passages in folder: ${passages}`);
```
</CodeGroup>
## Listing available folders
You can view available folders by listing them:
<CodeGroup>
```python title="python"
# list folders
folders = client.folders.list()
```
```typescript title="node.js"
// list folders
const folders = await client.folders.list();
```
</CodeGroup>
## Connecting a folder to an agent
When you attach a folder to an agent, the files inside the folder will become visible inside the agent's context window.
By default, only a limited "window" of the file will be visible to prevent context window overflow - the agent can use the file tools to browse through the files and search for information.
## Attaching the folder
### ADE
When you create a folder inside the ADE, it will be automatically attached to your agent.
You can also attach existing folders by clicking the "attach existing" button in the filesystem tab.
### API / SDK
You can attach a folder to an agent by specifying both the folder and agent IDs:
<CodeGroup>
```python title="python"
client.agents.folders.attach(agent_id=agent.id, folder_id=folder.id)
```
```typescript title="node.js"
await client.agents.folders.attach(agent.id, folder.id);
```
</CodeGroup>
Note that your agent and folder must be configured with the same embedding model, to ensure that the agent is able to search accross a common embedding space for archival memory.
## Detaching the folder
### ADE
To detach a folder from an agent, click the "detach" button in the folders tab.
### API / SDK
Detaching a folder will remove the files from the agent's context window:
<CodeGroup>
```python title="python"
client.agents.folders.detach(agent_id=agent.id, folder_id=folder.id)
```
```typescript title="node.js"
await client.agents.folders.detach(agent.id, folder.id);
```
</CodeGroup>