217 lines
6.7 KiB
Plaintext
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>
|