265 lines
8.6 KiB
Markdown
265 lines
8.6 KiB
Markdown
# Sequence Diagrams - Agent Media
|
|
|
|
## 1. Torrent Search and Download Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
participant User
|
|
participant FastAPI as FastAPI Server
|
|
participant Agent
|
|
participant PromptBuilder
|
|
participant LLM as LLM (DeepSeek/Ollama)
|
|
participant Tools as Tool Registry
|
|
participant Memory
|
|
participant Knaben as Knaben API
|
|
participant qBit as qBittorrent
|
|
|
|
User->>FastAPI: POST /v1/chat/completions<br/>"Find torrents for Inception 1080p"
|
|
FastAPI->>Agent: step(user_input)
|
|
|
|
Agent->>Memory: stm.get_recent_history()
|
|
Memory-->>Agent: conversation history
|
|
|
|
Agent->>PromptBuilder: build_system_prompt(memory)
|
|
PromptBuilder->>Memory: ltm.config, episodic state
|
|
Memory-->>PromptBuilder: context data
|
|
PromptBuilder-->>Agent: system prompt with context
|
|
|
|
Agent->>LLM: complete(messages)
|
|
LLM-->>Agent: {"action": {"name": "find_torrents", "args": {...}}}
|
|
|
|
Agent->>Agent: _parse_intent(response)
|
|
Agent->>Tools: execute find_torrents
|
|
Tools->>Knaben: search("Inception 1080p")
|
|
Knaben-->>Tools: torrent results
|
|
|
|
Tools->>Memory: episodic.store_search_results()
|
|
Memory-->>Tools: stored with indexes (1, 2, 3...)
|
|
|
|
Tools-->>Agent: {"status": "ok", "torrents": [...]}
|
|
|
|
Agent->>LLM: complete(messages + tool_result)
|
|
LLM-->>Agent: "I found 5 torrents for Inception..."
|
|
|
|
Agent->>Memory: stm.add_message("user", input)
|
|
Agent->>Memory: stm.add_message("assistant", response)
|
|
Agent->>Memory: save()
|
|
|
|
Agent-->>FastAPI: final response
|
|
FastAPI-->>User: JSON response
|
|
|
|
Note over User,qBit: User selects a torrent
|
|
|
|
User->>FastAPI: POST /v1/chat/completions<br/>"Download the 2nd one"
|
|
FastAPI->>Agent: step(user_input)
|
|
|
|
Agent->>PromptBuilder: build_system_prompt(memory)
|
|
PromptBuilder->>Memory: episodic.last_search_results
|
|
Note right of Memory: Results still in memory:<br/>1. Inception.2010.1080p...<br/>2. Inception.1080p.BluRay...
|
|
Memory-->>PromptBuilder: context with search results
|
|
PromptBuilder-->>Agent: prompt showing available results
|
|
|
|
Agent->>LLM: complete(messages)
|
|
LLM-->>Agent: {"action": {"name": "add_torrent_by_index", "args": {"index": 2}}}
|
|
|
|
Agent->>Tools: execute add_torrent_by_index(index=2)
|
|
Tools->>Memory: episodic.get_result_by_index(2)
|
|
Memory-->>Tools: torrent data with magnet link
|
|
|
|
Tools->>qBit: add_torrent(magnet_link)
|
|
qBit-->>Tools: success
|
|
|
|
Tools->>Memory: episodic.add_active_download()
|
|
Tools-->>Agent: {"status": "ok", "torrent_name": "Inception.1080p.BluRay"}
|
|
|
|
Agent->>LLM: complete(messages + tool_result)
|
|
LLM-->>Agent: "I've added Inception to qBittorrent!"
|
|
|
|
Agent-->>FastAPI: final response
|
|
FastAPI-->>User: JSON response
|
|
```
|
|
|
|
## 2. Folder Configuration Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
participant User
|
|
participant FastAPI as FastAPI Server
|
|
participant Agent
|
|
participant LLM as LLM
|
|
participant Tools as Tool Registry
|
|
participant FileManager
|
|
participant Memory
|
|
participant FS as Filesystem
|
|
|
|
User->>FastAPI: POST /v1/chat/completions<br/>"Set download folder to /mnt/media/downloads"
|
|
FastAPI->>Agent: step(user_input)
|
|
|
|
Agent->>LLM: complete(messages)
|
|
LLM-->>Agent: {"action": {"name": "set_path_for_folder", "args": {...}}}
|
|
|
|
Agent->>Tools: execute set_path_for_folder
|
|
Tools->>FileManager: set_folder_path("download", "/mnt/media/downloads")
|
|
|
|
FileManager->>FS: Path.exists()?
|
|
FS-->>FileManager: true
|
|
FileManager->>FS: Path.is_dir()?
|
|
FS-->>FileManager: true
|
|
FileManager->>FS: os.access(R_OK)?
|
|
FS-->>FileManager: true
|
|
|
|
FileManager->>Memory: ltm.set_config("download_folder", path)
|
|
FileManager->>Memory: save()
|
|
Memory->>FS: write ltm.json
|
|
|
|
FileManager-->>Tools: {"status": "ok", "path": "/mnt/media/downloads"}
|
|
Tools-->>Agent: result
|
|
|
|
Agent->>LLM: complete(messages + tool_result)
|
|
LLM-->>Agent: "Download folder set to /mnt/media/downloads"
|
|
|
|
Agent-->>FastAPI: final response
|
|
FastAPI-->>User: JSON response
|
|
```
|
|
|
|
## 3. Multi-Tool Workflow (Search Movie → Find Torrents → Download)
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
participant User
|
|
participant Agent
|
|
participant LLM as LLM
|
|
participant TMDB as TMDB API
|
|
participant Knaben as Knaben API
|
|
participant qBit as qBittorrent
|
|
participant Memory
|
|
|
|
User->>Agent: "Download Dune 2 in 4K"
|
|
|
|
rect rgb(240, 248, 255)
|
|
Note over Agent,TMDB: Step 1: Identify the movie
|
|
Agent->>LLM: complete(messages)
|
|
LLM-->>Agent: {"action": "find_media_imdb_id", "args": {"media_title": "Dune 2"}}
|
|
Agent->>TMDB: search_movie("Dune 2")
|
|
TMDB-->>Agent: {title: "Dune: Part Two", imdb_id: "tt15239678", year: 2024}
|
|
Agent->>Memory: stm.set_entity("last_media_search", {...})
|
|
end
|
|
|
|
rect rgb(255, 248, 240)
|
|
Note over Agent,Knaben: Step 2: Search for torrents
|
|
Agent->>LLM: complete(messages + movie_info)
|
|
LLM-->>Agent: {"action": "find_torrents", "args": {"media_title": "Dune Part Two 2024 4K"}}
|
|
Agent->>Knaben: search("Dune Part Two 2024 4K")
|
|
Knaben-->>Agent: [torrent1, torrent2, torrent3...]
|
|
Agent->>Memory: episodic.store_search_results()
|
|
end
|
|
|
|
rect rgb(240, 255, 240)
|
|
Note over Agent,qBit: Step 3: Add best torrent
|
|
Agent->>LLM: complete(messages + torrents)
|
|
LLM-->>Agent: {"action": "add_torrent_by_index", "args": {"index": 1}}
|
|
Agent->>Memory: episodic.get_result_by_index(1)
|
|
Memory-->>Agent: torrent with magnet
|
|
Agent->>qBit: add_torrent(magnet)
|
|
qBit-->>Agent: success
|
|
Agent->>Memory: episodic.add_active_download()
|
|
end
|
|
|
|
Agent->>LLM: complete(messages + all_results)
|
|
LLM-->>Agent: "I found Dune: Part Two (2024) and added the 4K torrent to qBittorrent!"
|
|
Agent-->>User: Final response
|
|
```
|
|
|
|
## 4. Error Handling Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
participant User
|
|
participant Agent
|
|
participant LLM as LLM
|
|
participant Tools as Tool Registry
|
|
participant Memory
|
|
participant API as External API
|
|
|
|
User->>Agent: "Download the 5th torrent"
|
|
|
|
Agent->>LLM: complete(messages)
|
|
LLM-->>Agent: {"action": "add_torrent_by_index", "args": {"index": 5}}
|
|
|
|
Agent->>Tools: execute add_torrent_by_index(5)
|
|
Tools->>Memory: episodic.get_result_by_index(5)
|
|
|
|
alt No search results
|
|
Memory-->>Tools: None (no previous search)
|
|
Tools-->>Agent: {"status": "error", "error": "not_found"}
|
|
Agent->>Memory: episodic.add_error("add_torrent_by_index", "not_found")
|
|
else Index out of range
|
|
Memory-->>Tools: None (only 3 results)
|
|
Tools-->>Agent: {"status": "error", "error": "not_found"}
|
|
Agent->>Memory: episodic.add_error("add_torrent_by_index", "not_found")
|
|
end
|
|
|
|
Agent->>LLM: complete(messages + error)
|
|
LLM-->>Agent: "I couldn't find torrent #5. Please search for torrents first."
|
|
|
|
Agent-->>User: Error explanation
|
|
|
|
Note over User,API: User searches first
|
|
|
|
User->>Agent: "Search for Matrix 1999"
|
|
Agent->>API: search("Matrix 1999")
|
|
API-->>Agent: [3 results]
|
|
Agent->>Memory: episodic.store_search_results()
|
|
Agent-->>User: "Found 3 torrents..."
|
|
|
|
User->>Agent: "Download the 2nd one"
|
|
Agent->>Memory: episodic.get_result_by_index(2)
|
|
Memory-->>Agent: torrent data ✓
|
|
Agent-->>User: "Added to qBittorrent!"
|
|
```
|
|
|
|
## 5. Background Events Flow
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
autonumber
|
|
participant User
|
|
participant Agent
|
|
participant Memory
|
|
participant qBit as qBittorrent
|
|
participant LLM as LLM
|
|
|
|
Note over qBit,Memory: Background: Download completes
|
|
qBit--)Memory: episodic.complete_download(task_id, file_path)
|
|
Memory->>Memory: add_background_event("download_complete", {...})
|
|
|
|
Note over User,LLM: Later: User sends a message
|
|
User->>Agent: "What's new?"
|
|
|
|
Agent->>Memory: episodic.get_unread_events()
|
|
Memory-->>Agent: [{type: "download_complete", data: {name: "Inception.1080p"}}]
|
|
|
|
Agent->>Agent: _check_unread_events()
|
|
Note right of Agent: Formats notification:<br/>"Download completed: Inception.1080p"
|
|
|
|
Agent->>LLM: complete(messages + notification)
|
|
LLM-->>Agent: "Good news! Inception.1080p has finished downloading."
|
|
|
|
Agent-->>User: Response with notification
|
|
```
|
|
|
|
## Legend
|
|
|
|
| Element | Description |
|
|
|---------|-------------|
|
|
| `rect rgb(...)` | Grouped steps in a workflow |
|
|
| `alt/else` | Conditional branches |
|
|
| `Note` | Explanatory notes |
|
|
| `-->>` | Response/return |
|
|
| `->>` | Request/call |
|
|
| `--))` | Async event |
|