Persistent Storage for AI Agents
Installation • Quick Start • API Reference • Architecture
AgSpace provides a file system-like storage layer for AI agents, with semantic search powered by pgvector.
- 📁 File System API — Familiar read/write/list operations
- 🔍 Semantic Search — Vector similarity search with pgvector
- 🏷️ Auto Tagging — Automatic metadata tagging
- 📦 Binary Storage — S3-compatible storage for large files
- ⚡ Async First — Built on asyncio for high performance
pip install agspace
# With OpenAI embeddings support
pip install agspace[openai]docker compose up -dThis starts:
- PostgreSQL with pgvector extension (port 5432)
- MinIO S3-compatible storage (port 9000)
export AGSPACE_POSTGRES_URL="postgresql+asyncpg://postgres:postgres@localhost:5432/agspace"
export AGSPACE_MINIO_ENDPOINT="http://localhost:9000"
export AGSPACE_MINIO_ACCESS_KEY="minioadmin"
export AGSPACE_MINIO_SECRET_KEY="minioadmin"
# Optional: for semantic search
export OPENAI_API_KEY="your-api-key"import asyncio
from agspace import Space
async def main():
# Mount a space for your agent
space = await Space.mount("agent://my-agent")
# Write files
await space.write("/memory/note.txt", "Remember to call Alice")
await space.write("/memory/config.json", {"theme": "dark"})
# Read files
note = await space.read("/memory/note.txt")
config = await space.read("/memory/config.json") # Returns dict
# List directory
files = await space.list("/memory")
for f in files:
print(f.name)
# Semantic search (requires OpenAI API key)
results = await space.search("Alice")
for r in results:
print(f"{r.node.path}: {r.score:.2f}")
await space.close()
asyncio.run(main())Each agent has a structured file system:
/
├── memory/ # Persistent memories and notes
│ ├── conversations/
│ └── knowledge/
├── skills/ # Learned skills and workflows
├── log/ # Activity logs
└── resources/ # Binary files (images, PDFs, etc.)
| Path | Storage | Use Case |
|---|---|---|
/memory/* |
PostgreSQL | Memories, notes, knowledge |
/skills/* |
PostgreSQL | Skills, workflows |
/log/* |
PostgreSQL | Logs, history |
/resources/* |
MinIO (S3) | Images, PDFs, binary files |
# Mount
space = await Space.mount("agent://my-agent")
# File Operations
await space.write(path, content, tags=None) # Write file
content = await space.read(path) # Read file
await space.delete(path, recursive=False) # Delete
await space.copy(src, dst) # Copy
await space.move(src, dst) # Move
# Directory Operations
await space.mkdir(path) # Create directory
nodes = await space.list(path, recursive=False) # List contents
exists = await space.exists(path) # Check existence
node = await space.stat(path) # Get file info
# Search
results = await space.search(query, path="/", limit=10) # Semantic search
matches = await space.grep(pattern, path="/") # Text search
files = await space.find(glob_pattern, path="/") # Find files
# Cleanup
await space.close()node = await space.stat("/memory/note.txt")
node.path # "/memory/note.txt"
node.name # "note.txt"
node.size # File size in bytes
node.node_type # NodeType.FILE or NodeType.DIRECTORY
node.metadata # Metadata object
node.created_at # Creation timestamp
node.updated_at # Last update timestampresults = await space.search("important meeting")
for r in results:
r.node # Node object
r.score # Similarity score (0-1)
r.snippet # Relevant text snippet| Variable | Default | Description |
|---|---|---|
AGSPACE_POSTGRES_URL |
postgresql+asyncpg://postgres:postgres@localhost:5432/agspace |
PostgreSQL connection |
AGSPACE_MINIO_ENDPOINT |
http://localhost:9000 |
MinIO endpoint |
AGSPACE_MINIO_BUCKET |
agspace |
MinIO bucket name |
AGSPACE_MINIO_ACCESS_KEY |
minioadmin |
MinIO access key |
AGSPACE_MINIO_SECRET_KEY |
minioadmin |
MinIO secret key |
AGSPACE_BLOB_DIR |
./data/blobs |
Local blob storage path |
OPENAI_API_KEY |
- | For semantic search embeddings |
from agspace import Space, AgSpaceConfig
config = AgSpaceConfig.default(
postgres_url="postgresql+asyncpg://...",
minio_endpoint="http://...",
)
space = await Space.mount("agent://my-agent", config)┌─────────────────────────────────────────────────────┐
│ Space API │
│ read() • write() • search() • list() • ... │
├─────────────────────────────────────────────────────┤
│ Combined Storage │
│ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ PostgreSQL │ │ MinIO │ │
│ │ + pgvector │ │ (S3-compatible) │ │
│ │ │ │ │ │
│ │ • Node metadata │ │ • /resources/* │ │
│ │ • Vector embeddings│ │ • Binary files │ │
│ │ • /memory/* │ │ • Large files │ │
│ │ • /skills/* │ │ │ │
│ │ • /log/* │ │ │ │
│ └─────────────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────┘
services:
postgres:
image: pgvector/pgvector:pg16
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: agspace
ports:
- "5432:5432"
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports:
- "9000:9000"
- "9001:9001"# Save a memory
await space.write("/memory/meetings/2024-01-15.md", """
# Team Sync
- Alice: Working on auth
- Bob: Fixing bugs
- Next sync: Friday
""")
# Search memories
results = await space.search("Alice working on")# Save a skill
await space.write("/skills/summarize.md", """
# Summarize Text
## Steps
1. Read the input text
2. Identify key points
3. Write concise summary
## Example
Input: "The quick brown fox..."
Output: "Fox jumps over dog."
""")# Save an image
with open("chart.png", "rb") as f:
await space.write("/resources/charts/sales.png", f.read())
# Read it back
data = await space.read("/resources/charts/sales.png", as_text=False)MIT
