8.6 KiB
8.6 KiB
Sequence Diagrams - Agent Media
1. Torrent Search and Download Flow
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
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)
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
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
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 |