9.5 KiB
9.5 KiB
Class Diagram - Agent Media
classDiagram
direction TB
%% ===========================================
%% MEMORY SYSTEM
%% ===========================================
class Memory {
+Path storage_dir
+Path ltm_file
+LongTermMemory ltm
+ShortTermMemory stm
+EpisodicMemory episodic
+__init__(storage_dir: str)
+save() void
+get_context_for_prompt() Dict
+get_full_state() Dict
+clear_session() void
}
class LongTermMemory {
+Dict config
+Dict preferences
+Dict~str, List~ library
+List~Dict~ following
+get_config(key: str) Any
+set_config(key: str, value: Any) void
+has_config(key: str) bool
+add_to_library(media_type: str, media: Dict) void
+get_library(media_type: str) List
+follow_show(show: Dict) void
+to_dict() Dict
+from_dict(data: Dict)$ LongTermMemory
}
class ShortTermMemory {
+List~Dict~ conversation_history
+Dict current_workflow
+Dict extracted_entities
+str current_topic
+int max_history
+add_message(role: str, content: str) void
+get_recent_history(n: int) List
+start_workflow(type: str, target: Dict) void
+update_workflow_stage(stage: str) void
+end_workflow() void
+set_entity(key: str, value: Any) void
+get_entity(key: str) Any
+clear() void
+to_dict() Dict
}
class EpisodicMemory {
+Dict last_search_results
+List~Dict~ active_downloads
+List~Dict~ recent_errors
+Dict pending_question
+List~Dict~ background_events
+store_search_results(query: str, results: List) void
+get_result_by_index(index: int) Dict
+get_search_results() Dict
+add_active_download(download: Dict) void
+complete_download(task_id: str, path: str) Dict
+add_error(action: str, error: str) void
+set_pending_question(question: str, options: List) void
+resolve_pending_question(index: int) Dict
+add_background_event(type: str, data: Dict) void
+get_unread_events() List
+clear() void
+to_dict() Dict
}
Memory *-- LongTermMemory : ltm
Memory *-- ShortTermMemory : stm
Memory *-- EpisodicMemory : episodic
%% ===========================================
%% AGENT SYSTEM
%% ===========================================
class Agent {
+LLMClient llm
+Memory memory
+Dict~str, Tool~ tools
+PromptBuilder prompt_builder
+int max_tool_iterations
+__init__(llm: LLMClient, memory: Memory)
+step(user_input: str) str
-_parse_intent(text: str) Dict
-_execute_action(intent: Dict) Dict
-_check_unread_events() str
}
class LLMClient {
<<Protocol>>
+complete(messages: List) str
}
class DeepSeekClient {
+str api_key
+str model
+str base_url
+complete(messages: List) str
}
class OllamaClient {
+str base_url
+str model
+complete(messages: List) str
}
class PromptBuilder {
+Dict~str, Tool~ tools
+__init__(tools: Dict)
+build_system_prompt(memory: Memory) str
-_format_tools_description() str
-_format_episodic_context(memory: Memory) str
-_format_stm_context(memory: Memory) str
}
class Tool {
<<dataclass>>
+str name
+str description
+Callable func
+Dict parameters
}
Agent --> LLMClient : uses
Agent --> Memory : uses
Agent --> PromptBuilder : uses
Agent --> Tool : executes
DeepSeekClient ..|> LLMClient
OllamaClient ..|> LLMClient
PromptBuilder --> Tool : formats
%% ===========================================
%% DOMAIN - MOVIES
%% ===========================================
class Movie {
<<Entity>>
+ImdbId imdb_id
+MovieTitle title
+ReleaseYear release_year
+Quality quality
+FilePath file_path
+FileSize file_size
+int tmdb_id
+datetime added_at
}
class MovieTitle {
<<ValueObject>>
+str value
+__init__(value: str)
}
class ReleaseYear {
<<ValueObject>>
+int value
+__init__(value: int)
}
class Quality {
<<ValueObject>>
+str value
+__init__(value: str)
}
class MovieRepository {
<<Interface>>
+save(movie: Movie) void
+find_by_imdb_id(imdb_id: ImdbId) Movie
+find_all() List~Movie~
+delete(imdb_id: ImdbId) bool
+exists(imdb_id: ImdbId) bool
}
Movie --> MovieTitle
Movie --> ReleaseYear
Movie --> Quality
Movie --> ImdbId
%% ===========================================
%% DOMAIN - TV SHOWS
%% ===========================================
class TVShow {
<<Entity>>
+ImdbId imdb_id
+str title
+int seasons_count
+ShowStatus status
+int tmdb_id
+str first_air_date
+datetime added_at
}
class ShowStatus {
<<Enum>>
CONTINUING
ENDED
UNKNOWN
+from_string(value: str)$ ShowStatus
}
class TVShowRepository {
<<Interface>>
+save(show: TVShow) void
+find_by_imdb_id(imdb_id: ImdbId) TVShow
+find_all() List~TVShow~
+delete(imdb_id: ImdbId) bool
}
TVShow --> ShowStatus
TVShow --> ImdbId
%% ===========================================
%% DOMAIN - SHARED
%% ===========================================
class ImdbId {
<<ValueObject>>
+str value
+__init__(value: str)
+__str__() str
}
class FilePath {
<<ValueObject>>
+str value
+__init__(value: str)
}
class FileSize {
<<ValueObject>>
+int bytes
+__init__(bytes: int)
+to_human_readable() str
}
%% ===========================================
%% INFRASTRUCTURE - PERSISTENCE
%% ===========================================
class JsonMovieRepository {
+Memory memory
+__init__(memory: Memory)
+save(movie: Movie) void
+find_by_imdb_id(imdb_id: ImdbId) Movie
+find_all() List~Movie~
+delete(imdb_id: ImdbId) bool
}
class JsonTVShowRepository {
+Memory memory
+__init__(memory: Memory)
+save(show: TVShow) void
+find_by_imdb_id(imdb_id: ImdbId) TVShow
+find_all() List~TVShow~
+delete(imdb_id: ImdbId) bool
}
JsonMovieRepository ..|> MovieRepository
JsonTVShowRepository ..|> TVShowRepository
JsonMovieRepository --> Memory
JsonTVShowRepository --> Memory
%% ===========================================
%% INFRASTRUCTURE - API CLIENTS
%% ===========================================
class TMDBClient {
+str api_key
+str base_url
+search_movie(title: str) TMDBSearchResult
+search_tv(title: str) TMDBSearchResult
+get_external_ids(tmdb_id: int) Dict
}
class KnabenClient {
+str base_url
+search(query: str, limit: int) List~TorrentResult~
}
class QBittorrentClient {
+str host
+str username
+str password
+add_torrent(magnet: str) bool
+get_torrents() List
}
%% ===========================================
%% INFRASTRUCTURE - FILESYSTEM
%% ===========================================
class FileManager {
+Memory memory
+__init__(memory: Memory)
+set_folder_path(name: str, path: str) Dict
+list_folder(type: str, path: str) Dict
+move_file(source: str, dest: str) Dict
}
FileManager --> Memory
%% ===========================================
%% APPLICATION - USE CASES
%% ===========================================
class SearchMovieUseCase {
+TMDBClient tmdb_client
+execute(title: str) SearchMovieResponse
}
class SearchTorrentsUseCase {
+KnabenClient knaben_client
+execute(title: str, limit: int) SearchTorrentsResponse
}
class AddTorrentUseCase {
+QBittorrentClient qbittorrent_client
+execute(magnet: str) AddTorrentResponse
}
class SetFolderPathUseCase {
+FileManager file_manager
+execute(folder_name: str, path: str) SetFolderPathResponse
}
class ListFolderUseCase {
+FileManager file_manager
+execute(folder_type: str, path: str) ListFolderResponse
}
SearchMovieUseCase --> TMDBClient
SearchTorrentsUseCase --> KnabenClient
AddTorrentUseCase --> QBittorrentClient
SetFolderPathUseCase --> FileManager
ListFolderUseCase --> FileManager
Legend
| Symbol | Meaning |
|---|---|
<<Entity>> |
Domain entity with identity |
<<ValueObject>> |
Immutable value object |
<<Interface>> |
Abstract interface/protocol |
<<Enum>> |
Enumeration |
<<dataclass>> |
Python dataclass |
<<Protocol>> |
Python Protocol (structural typing) |
*-- |
Composition (owns) |
--> |
Association (uses) |
..|> |
Implementation |
Architecture Layers
- Domain Layer - Business entities and rules (Movie, TVShow, ValueObjects)
- Application Layer - Use cases orchestrating business logic
- Infrastructure Layer - External services (APIs, filesystem, persistence)
- Agent Layer - AI agent, LLM clients, tools, prompts