infra: reorganized repo
This commit is contained in:
264
docs/sequence_diagram.md
Normal file
264
docs/sequence_diagram.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# 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 |
|
||||
Reference in New Issue
Block a user