401 lines
9.1 KiB
Markdown
401 lines
9.1 KiB
Markdown
# Agent Media 🎬
|
|
|
|
An AI-powered agent for managing your local media library with natural language. Search, download, and organize movies and TV shows effortlessly.
|
|
|
|
## Features
|
|
|
|
- 🤖 **Natural Language Interface**: Talk to your media library in plain language
|
|
- 🔍 **Smart Search**: Find movies and TV shows via TMDB
|
|
- 📥 **Torrent Integration**: Search and download via qBittorrent
|
|
- 🧠 **Contextual Memory**: Remembers your preferences and conversation history
|
|
- 📁 **Auto-Organization**: Keeps your media library tidy
|
|
- 🌐 **API Compatible**: OpenAI-compatible API for easy integration
|
|
|
|
## Architecture
|
|
|
|
Built with **Domain-Driven Design (DDD)** principles:
|
|
|
|
```
|
|
agent_media/
|
|
├── agent/ # AI agent orchestration
|
|
├── application/ # Use cases & DTOs
|
|
├── domain/ # Business logic & entities
|
|
└── infrastructure/ # External services & persistence
|
|
```
|
|
|
|
See [architecture_diagram.md](docs/architecture_diagram.md) for architectural details.
|
|
|
|
## Quick Start
|
|
|
|
### Prerequisites
|
|
|
|
- Python 3.12+
|
|
- Poetry
|
|
- qBittorrent (optional, for downloads)
|
|
- API Keys:
|
|
- DeepSeek API key (or Ollama for local LLM)
|
|
- TMDB API key
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone https://github.com/your-username/agent-media.git
|
|
cd agent-media
|
|
|
|
# Install dependencies
|
|
poetry install
|
|
|
|
# Copy environment template
|
|
cp .env.example .env
|
|
|
|
# Edit .env with your API keys
|
|
nano .env
|
|
```
|
|
|
|
### Configuration
|
|
|
|
Edit `.env`:
|
|
|
|
```bash
|
|
# LLM Provider (deepseek or ollama)
|
|
LLM_PROVIDER=deepseek
|
|
DEEPSEEK_API_KEY=your-api-key-here
|
|
|
|
# TMDB (for movie/TV show metadata)
|
|
TMDB_API_KEY=your-tmdb-key-here
|
|
|
|
# qBittorrent (optional)
|
|
QBITTORRENT_HOST=http://localhost:8080
|
|
QBITTORRENT_USERNAME=admin
|
|
QBITTORRENT_PASSWORD=adminadmin
|
|
```
|
|
|
|
### Run
|
|
|
|
```bash
|
|
# Start the API server
|
|
poetry run uvicorn app:app --reload
|
|
|
|
# Or with Docker
|
|
docker-compose up
|
|
```
|
|
|
|
The API will be available at `http://localhost:8000`
|
|
|
|
## Usage
|
|
|
|
### Via API
|
|
|
|
```bash
|
|
# Health check
|
|
curl http://localhost:8000/health
|
|
|
|
# Chat with the agent
|
|
curl -X POST http://localhost:8000/v1/chat/completions \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"model": "agent-media",
|
|
"messages": [
|
|
{"role": "user", "content": "Find Inception 1080p"}
|
|
]
|
|
}'
|
|
```
|
|
|
|
### Via OpenWebUI
|
|
|
|
Agent Media is compatible with [OpenWebUI](https://github.com/open-webui/open-webui):
|
|
|
|
1. Add as OpenAI-compatible endpoint: `http://localhost:8000/v1`
|
|
2. Model name: `agent-media`
|
|
3. Start chatting!
|
|
|
|
### Example Conversations
|
|
|
|
```
|
|
You: Find Inception in 1080p
|
|
Agent: I found 3 torrents for Inception:
|
|
1. Inception.2010.1080p.BluRay.x264 (150 seeders)
|
|
2. Inception.2010.1080p.WEB-DL.x265 (80 seeders)
|
|
3. Inception.2010.720p.BluRay (45 seeders)
|
|
|
|
You: Download the first one
|
|
Agent: Added to qBittorrent! Download started.
|
|
|
|
You: List my downloads
|
|
Agent: You have 1 active download:
|
|
- Inception.2010.1080p.BluRay.x264 (45% complete)
|
|
```
|
|
|
|
## Available Tools
|
|
|
|
The agent has access to these tools:
|
|
|
|
| Tool | Description |
|
|
|------|-------------|
|
|
| `find_media_imdb_id` | Search for movies/TV shows on TMDB |
|
|
| `find_torrents` | Search for torrents |
|
|
| `get_torrent_by_index` | Get torrent details by index |
|
|
| `add_torrent_by_index` | Download torrent by index |
|
|
| `add_torrent_to_qbittorrent` | Add torrent via magnet link |
|
|
| `set_path_for_folder` | Configure folder paths |
|
|
| `list_folder` | List folder contents |
|
|
|
|
## Memory System
|
|
|
|
Agent Media uses a three-tier memory system:
|
|
|
|
### Long-Term Memory (LTM)
|
|
- **Persistent** (saved to JSON)
|
|
- Configuration, preferences, media library
|
|
- Survives restarts
|
|
|
|
### Short-Term Memory (STM)
|
|
- **Session-based** (RAM only)
|
|
- Conversation history, current workflow
|
|
- Cleared on restart
|
|
|
|
### Episodic Memory
|
|
- **Transient** (RAM only)
|
|
- Search results, active downloads, recent errors
|
|
- Cleared frequently
|
|
|
|
## Development
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
agent_media/
|
|
├── agent/
|
|
│ ├── agent.py # Main agent orchestrator
|
|
│ ├── prompts.py # System prompt builder
|
|
│ ├── registry.py # Tool registration
|
|
│ ├── tools/ # Tool implementations
|
|
│ └── llm/ # LLM clients (DeepSeek, Ollama)
|
|
├── application/
|
|
│ ├── movies/ # Movie use cases
|
|
│ ├── torrents/ # Torrent use cases
|
|
│ └── filesystem/ # Filesystem use cases
|
|
├── domain/
|
|
│ ├── movies/ # Movie entities & value objects
|
|
│ ├── tv_shows/ # TV show entities
|
|
│ ├── subtitles/ # Subtitle entities
|
|
│ └── shared/ # Shared value objects
|
|
├── infrastructure/
|
|
│ ├── api/ # External API clients
|
|
│ │ ├── tmdb/ # TMDB client
|
|
│ │ ├── knaben/ # Torrent search
|
|
│ │ └── qbittorrent/ # qBittorrent client
|
|
│ ├── filesystem/ # File operations
|
|
│ └── persistence/ # Memory & repositories
|
|
├── tests/ # Test suite (~500 tests)
|
|
└── docs/ # Documentation
|
|
```
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
# Run all tests
|
|
poetry run pytest
|
|
|
|
# Run with coverage
|
|
poetry run pytest --cov
|
|
|
|
# Run specific test file
|
|
poetry run pytest tests/test_agent.py
|
|
|
|
# Run specific test
|
|
poetry run pytest tests/test_agent.py::TestAgent::test_step
|
|
```
|
|
|
|
### Code Quality
|
|
|
|
```bash
|
|
# Linting
|
|
poetry run ruff check .
|
|
|
|
# Formatting
|
|
poetry run black .
|
|
|
|
# Type checking (if mypy is installed)
|
|
poetry run mypy .
|
|
```
|
|
|
|
### Adding a New Tool
|
|
|
|
Quick example:
|
|
|
|
```python
|
|
# 1. Create the tool function in agent/tools/api.py
|
|
def my_new_tool(param: str) -> Dict[str, Any]:
|
|
"""Tool description."""
|
|
memory = get_memory()
|
|
# Implementation
|
|
return {"status": "ok", "data": "result"}
|
|
|
|
# 2. Register in agent/registry.py
|
|
Tool(
|
|
name="my_new_tool",
|
|
description="What this tool does",
|
|
func=api_tools.my_new_tool,
|
|
parameters={
|
|
"type": "object",
|
|
"properties": {
|
|
"param": {"type": "string", "description": "Parameter description"},
|
|
},
|
|
"required": ["param"],
|
|
},
|
|
),
|
|
```
|
|
|
|
## Docker
|
|
|
|
### Build
|
|
|
|
```bash
|
|
docker build -t agent-media .
|
|
```
|
|
|
|
### Run
|
|
|
|
```bash
|
|
docker run -p 8000:8000 \
|
|
-e DEEPSEEK_API_KEY=your-key \
|
|
-e TMDB_API_KEY=your-key \
|
|
-v $(pwd)/memory_data:/app/memory_data \
|
|
agent-media
|
|
```
|
|
|
|
### Docker Compose
|
|
|
|
```bash
|
|
# Start all services (agent + qBittorrent)
|
|
docker-compose up -d
|
|
|
|
# View logs
|
|
docker-compose logs -f
|
|
|
|
# Stop
|
|
docker-compose down
|
|
```
|
|
|
|
## API Documentation
|
|
|
|
### Endpoints
|
|
|
|
#### `GET /health`
|
|
Health check endpoint.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"version": "0.2.0"
|
|
}
|
|
```
|
|
|
|
#### `GET /v1/models`
|
|
List available models (OpenAI-compatible).
|
|
|
|
#### `POST /v1/chat/completions`
|
|
Chat with the agent (OpenAI-compatible).
|
|
|
|
**Request:**
|
|
```json
|
|
{
|
|
"model": "agent-media",
|
|
"messages": [
|
|
{"role": "user", "content": "Find Inception"}
|
|
],
|
|
"stream": false
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"id": "chatcmpl-xxx",
|
|
"object": "chat.completion",
|
|
"created": 1234567890,
|
|
"model": "agent-media",
|
|
"choices": [{
|
|
"index": 0,
|
|
"message": {
|
|
"role": "assistant",
|
|
"content": "I found Inception (2010)..."
|
|
},
|
|
"finish_reason": "stop"
|
|
}]
|
|
}
|
|
```
|
|
|
|
#### `GET /memory/state`
|
|
View full memory state (debug).
|
|
|
|
#### `POST /memory/clear-session`
|
|
Clear session memories (STM + Episodic).
|
|
|
|
## Troubleshooting
|
|
|
|
### Agent doesn't respond
|
|
- Check API keys in `.env`
|
|
- Verify LLM provider is running (Ollama) or accessible (DeepSeek)
|
|
- Check logs: `docker-compose logs agent-media`
|
|
|
|
### qBittorrent connection failed
|
|
- Verify qBittorrent is running
|
|
- Check `QBITTORRENT_HOST` in `.env`
|
|
- Ensure Web UI is enabled in qBittorrent settings
|
|
|
|
### Memory not persisting
|
|
- Check `memory_data/` directory exists and is writable
|
|
- Verify volume mounts in Docker
|
|
|
|
### Tests failing
|
|
- Run `poetry install` to ensure dependencies are up to date
|
|
- Check logs for specific error messages
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome!
|
|
|
|
### Development Workflow
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
3. Make your changes
|
|
4. Run tests: `poetry run pytest`
|
|
5. Run linting: `poetry run ruff check . && poetry run black .`
|
|
6. Commit: `git commit -m "Add my feature"`
|
|
7. Push: `git push origin feature/my-feature`
|
|
8. Create a Pull Request
|
|
|
|
## Documentation
|
|
|
|
- [Architecture Diagram](docs/architecture_diagram.md) - System architecture overview
|
|
- [Class Diagram](docs/class_diagram.md) - Class structure and relationships
|
|
- [Component Diagram](docs/component_diagram.md) - Component interactions
|
|
- [Sequence Diagram](docs/sequence_diagram.md) - Sequence flows
|
|
- [Flowchart](docs/flowchart.md) - System flowcharts
|
|
|
|
## License
|
|
|
|
MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
|
## Acknowledgments
|
|
|
|
- [DeepSeek](https://www.deepseek.com/) - LLM provider
|
|
- [TMDB](https://www.themoviedb.org/) - Movie database
|
|
- [qBittorrent](https://www.qbittorrent.org/) - Torrent client
|
|
- [FastAPI](https://fastapi.tiangolo.com/) - Web framework
|
|
|
|
## Support
|
|
|
|
- 📧 Email: francois.hodiaumont@gmail.com
|
|
- 🐛 Issues: [GitHub Issues](https://github.com/your-username/agent-media/issues)
|
|
- 💬 Discussions: [GitHub Discussions](https://github.com/your-username/agent-media/discussions)
|
|
|
|
---
|
|
|
|
Made with ❤️ by Francwa
|