Files
alfred/brain/docs/flowchart.md

13 KiB

Flowcharts - Agent Media

1. Main Application Flow

flowchart TD
    START([Application Start]) --> INIT_MEM[Initialize Memory Context<br/>init_memory]
    INIT_MEM --> INIT_LLM{LLM Provider?}
    
    INIT_LLM -->|OLLAMA| OLLAMA[Create OllamaClient]
    INIT_LLM -->|DEEPSEEK| DEEPSEEK[Create DeepSeekClient]
    
    OLLAMA --> INIT_AGENT[Create Agent]
    DEEPSEEK --> INIT_AGENT
    
    INIT_AGENT --> INIT_TOOLS[Register Tools<br/>make_tools]
    INIT_TOOLS --> START_SERVER[Start FastAPI Server<br/>:8000]
    
    START_SERVER --> WAIT_REQ[/Wait for Request/]
    
    WAIT_REQ --> REQ_TYPE{Request Type?}
    
    REQ_TYPE -->|GET /health| HEALTH[Return health status]
    REQ_TYPE -->|GET /v1/models| MODELS[Return model list]
    REQ_TYPE -->|GET /memory/state| MEM_STATE[Return memory state]
    REQ_TYPE -->|POST /memory/clear-session| CLEAR_SESSION[Clear STM + Episodic]
    REQ_TYPE -->|POST /v1/chat/completions| CHAT[Process Chat Request]
    
    HEALTH --> WAIT_REQ
    MODELS --> WAIT_REQ
    MEM_STATE --> WAIT_REQ
    CLEAR_SESSION --> WAIT_REQ
    CHAT --> AGENT_STEP[agent.step]
    AGENT_STEP --> RETURN_RESP[Return Response]
    RETURN_RESP --> WAIT_REQ

2. Agent Step Flow (Core Logic)

flowchart TD
    START([agent.step called]) --> GET_MEM[Get Memory from Context]
    GET_MEM --> CHECK_EVENTS[Check Unread Events]
    
    CHECK_EVENTS --> HAS_EVENTS{Has Events?}
    HAS_EVENTS -->|Yes| FORMAT_EVENTS[Format Event Notifications]
    HAS_EVENTS -->|No| BUILD_PROMPT
    FORMAT_EVENTS --> BUILD_PROMPT
    
    BUILD_PROMPT[Build System Prompt<br/>with Memory Context]
    BUILD_PROMPT --> INIT_MSGS[Initialize Messages Array]
    
    INIT_MSGS --> ADD_SYSTEM[Add System Prompt]
    ADD_SYSTEM --> GET_HISTORY[Get STM History]
    GET_HISTORY --> ADD_HISTORY[Add History Messages]
    ADD_HISTORY --> ADD_NOTIF{Has Notifications?}
    
    ADD_NOTIF -->|Yes| ADD_NOTIF_MSG[Add Notification Message]
    ADD_NOTIF -->|No| ADD_USER
    ADD_NOTIF_MSG --> ADD_USER[Add User Input]
    
    ADD_USER --> LOOP_START[/Tool Execution Loop/]
    
    LOOP_START --> CHECK_ITER{iteration < max?}
    CHECK_ITER -->|No| MAX_REACHED[Request Final Response]
    CHECK_ITER -->|Yes| CALL_LLM[Call LLM.complete]
    
    MAX_REACHED --> FINAL_LLM[Call LLM.complete]
    FINAL_LLM --> SAVE_FINAL[Save to STM History]
    SAVE_FINAL --> RETURN_FINAL([Return Response])
    
    CALL_LLM --> PARSE_INTENT[Parse Intent from Response]
    PARSE_INTENT --> IS_TOOL{Is Tool Call?}
    
    IS_TOOL -->|No| SAVE_HISTORY[Save to STM History]
    SAVE_HISTORY --> SAVE_LTM[Save LTM]
    SAVE_LTM --> RETURN_TEXT([Return Text Response])
    
    IS_TOOL -->|Yes| EXEC_TOOL[Execute Tool]
    EXEC_TOOL --> ADD_RESULT[Add Tool Result to Messages]
    ADD_RESULT --> INC_ITER[iteration++]
    INC_ITER --> LOOP_START

3. Tool Execution Flow

flowchart TD
    START([_execute_action called]) --> GET_ACTION[Extract action name & args]
    GET_ACTION --> FIND_TOOL{Tool exists?}
    
    FIND_TOOL -->|No| UNKNOWN[Return unknown_tool error]
    UNKNOWN --> END_ERR([Return Error])
    
    FIND_TOOL -->|Yes| CALL_FUNC[Call tool.func with args]
    
    CALL_FUNC --> EXEC_OK{Execution OK?}
    
    EXEC_OK -->|TypeError| BAD_ARGS[Log bad arguments error]
    EXEC_OK -->|Exception| EXEC_ERR[Log execution error]
    EXEC_OK -->|Success| CHECK_RESULT{Result has error?}
    
    BAD_ARGS --> ADD_ERR_MEM[Add error to Episodic Memory]
    EXEC_ERR --> ADD_ERR_MEM
    ADD_ERR_MEM --> END_ERR
    
    CHECK_RESULT -->|Yes| ADD_ERR_MEM2[Add error to Episodic Memory]
    ADD_ERR_MEM2 --> RETURN_RESULT
    CHECK_RESULT -->|No| RETURN_RESULT([Return Result])

4. Prompt Building Flow

flowchart TD
    START([build_system_prompt called]) --> GET_MEM[Get Memory from Context]
    
    GET_MEM --> FORMAT_TOOLS[Format Tools Description]
    FORMAT_TOOLS --> FORMAT_PARAMS[Format Parameters Description]
    
    FORMAT_PARAMS --> CHECK_MISSING[Check Missing Required Params]
    CHECK_MISSING --> HAS_MISSING{Has Missing?}
    
    HAS_MISSING -->|Yes| FORMAT_MISSING[Format Missing Params Info]
    HAS_MISSING -->|No| FORMAT_EPISODIC
    FORMAT_MISSING --> FORMAT_EPISODIC
    
    FORMAT_EPISODIC[Format Episodic Context]
    FORMAT_EPISODIC --> HAS_SEARCH{Has Search Results?}
    
    HAS_SEARCH -->|Yes| ADD_SEARCH[Add Search Results Summary]
    HAS_SEARCH -->|No| CHECK_PENDING
    ADD_SEARCH --> CHECK_PENDING
    
    CHECK_PENDING{Has Pending Question?}
    CHECK_PENDING -->|Yes| ADD_PENDING[Add Pending Question]
    CHECK_PENDING -->|No| CHECK_DOWNLOADS
    ADD_PENDING --> CHECK_DOWNLOADS
    
    CHECK_DOWNLOADS{Has Active Downloads?}
    CHECK_DOWNLOADS -->|Yes| ADD_DOWNLOADS[Add Downloads Status]
    CHECK_DOWNLOADS -->|No| CHECK_ERRORS
    ADD_DOWNLOADS --> CHECK_ERRORS
    
    CHECK_ERRORS{Has Recent Errors?}
    CHECK_ERRORS -->|Yes| ADD_ERRORS[Add Last Error]
    CHECK_ERRORS -->|No| FORMAT_STM
    ADD_ERRORS --> FORMAT_STM
    
    FORMAT_STM[Format STM Context]
    FORMAT_STM --> HAS_WORKFLOW{Has Workflow?}
    
    HAS_WORKFLOW -->|Yes| ADD_WORKFLOW[Add Workflow Info]
    HAS_WORKFLOW -->|No| CHECK_TOPIC
    ADD_WORKFLOW --> CHECK_TOPIC
    
    CHECK_TOPIC{Has Topic?}
    CHECK_TOPIC -->|Yes| ADD_TOPIC[Add Current Topic]
    CHECK_TOPIC -->|No| CHECK_ENTITIES
    ADD_TOPIC --> CHECK_ENTITIES
    
    CHECK_ENTITIES{Has Entities?}
    CHECK_ENTITIES -->|Yes| ADD_ENTITIES[Add Extracted Entities]
    CHECK_ENTITIES -->|No| BUILD_FINAL
    ADD_ENTITIES --> BUILD_FINAL
    
    BUILD_FINAL[Assemble Final Prompt]
    BUILD_FINAL --> RETURN([Return System Prompt])

5. Memory System Flow

flowchart TD
    subgraph Initialization
        INIT([init_memory called]) --> CREATE_MEM[Create Memory Instance]
        CREATE_MEM --> LOAD_LTM{LTM file exists?}
        LOAD_LTM -->|Yes| READ_FILE[Read ltm.json]
        LOAD_LTM -->|No| CREATE_DEFAULT[Create Default LTM]
        READ_FILE --> PARSE_JSON{Parse OK?}
        PARSE_JSON -->|Yes| RESTORE_LTM[Restore LTM from Dict]
        PARSE_JSON -->|No| CREATE_DEFAULT
        CREATE_DEFAULT --> CREATE_STM[Create Empty STM]
        RESTORE_LTM --> CREATE_STM
        CREATE_STM --> CREATE_EPIS[Create Empty Episodic]
        CREATE_EPIS --> SET_CTX[Set in Context Variable]
        SET_CTX --> RETURN_MEM([Return Memory])
    end
    
    subgraph Access
        GET([get_memory called]) --> CHECK_CTX{Context has Memory?}
        CHECK_CTX -->|Yes| RETURN_CTX([Return Memory])
        CHECK_CTX -->|No| RAISE_ERR[Raise RuntimeError]
    end
    
    subgraph Save
        SAVE([memory.save called]) --> SERIALIZE[Serialize LTM to Dict]
        SERIALIZE --> WRITE_JSON[Write to ltm.json]
        WRITE_JSON --> SAVE_OK{Write OK?}
        SAVE_OK -->|Yes| DONE([Done])
        SAVE_OK -->|No| LOG_ERR[Log Error & Raise]
    end

6. Torrent Search & Download Flow

flowchart TD
    subgraph Search
        SEARCH_START([find_torrent called]) --> CREATE_UC[Create SearchTorrentsUseCase]
        CREATE_UC --> EXEC_SEARCH[Execute Search via Knaben API]
        EXEC_SEARCH --> SEARCH_OK{Results Found?}
        
        SEARCH_OK -->|No| RETURN_ERR([Return Error])
        SEARCH_OK -->|Yes| GET_MEM[Get Memory]
        GET_MEM --> STORE_RESULTS[Store in Episodic Memory<br/>with indexes 1,2,3...]
        STORE_RESULTS --> SET_TOPIC[Set Topic: selecting_torrent]
        SET_TOPIC --> RETURN_RESULTS([Return Results])
    end
    
    subgraph "Get by Index"
        GET_START([get_torrent_by_index called]) --> GET_MEM2[Get Memory]
        GET_MEM2 --> HAS_RESULTS{Has Search Results?}
        
        HAS_RESULTS -->|No| NO_RESULTS([Return not_found Error])
        HAS_RESULTS -->|Yes| FIND_INDEX[Find Result by Index]
        FIND_INDEX --> FOUND{Found?}
        
        FOUND -->|No| NOT_FOUND([Return not_found Error])
        FOUND -->|Yes| RETURN_TORRENT([Return Torrent Data])
    end
    
    subgraph "Add by Index"
        ADD_START([add_torrent_by_index called]) --> CALL_GET[Call get_torrent_by_index]
        CALL_GET --> GET_OK{Got Torrent?}
        
        GET_OK -->|No| RETURN_GET_ERR([Return Error])
        GET_OK -->|Yes| HAS_MAGNET{Has Magnet Link?}
        
        HAS_MAGNET -->|No| NO_MAGNET([Return no_magnet Error])
        HAS_MAGNET -->|Yes| CALL_ADD[Call add_torrent_to_qbittorrent]
        CALL_ADD --> ADD_OK{Added OK?}
        
        ADD_OK -->|No| RETURN_ADD_ERR([Return Error])
        ADD_OK -->|Yes| ADD_NAME[Add torrent_name to Result]
        ADD_NAME --> RETURN_SUCCESS([Return Success])
    end
    
    subgraph "Add to qBittorrent"
        QB_START([add_torrent_to_qbittorrent called]) --> CREATE_UC2[Create AddTorrentUseCase]
        CREATE_UC2 --> EXEC_ADD[Execute Add via qBittorrent API]
        EXEC_ADD --> QB_OK{Added OK?}
        
        QB_OK -->|No| QB_ERR([Return Error])
        QB_OK -->|Yes| GET_MEM3[Get Memory]
        GET_MEM3 --> FIND_NAME[Find Torrent Name from Search]
        FIND_NAME --> ADD_DOWNLOAD[Add to Active Downloads]
        ADD_DOWNLOAD --> SET_TOPIC2[Set Topic: downloading]
        SET_TOPIC2 --> END_WORKFLOW[End Current Workflow]
        END_WORKFLOW --> QB_SUCCESS([Return Success])
    end

7. Filesystem Operations Flow

flowchart TD
    subgraph "Set Folder Path"
        SET_START([set_path_for_folder called]) --> VALIDATE_NAME[Validate Folder Name]
        VALIDATE_NAME --> NAME_OK{Valid Name?}
        
        NAME_OK -->|No| INVALID_NAME([Return validation_failed])
        NAME_OK -->|Yes| RESOLVE_PATH[Resolve Path]
        
        RESOLVE_PATH --> PATH_EXISTS{Path Exists?}
        PATH_EXISTS -->|No| NOT_EXISTS([Return invalid_path])
        PATH_EXISTS -->|Yes| IS_DIR{Is Directory?}
        
        IS_DIR -->|No| NOT_DIR([Return invalid_path])
        IS_DIR -->|Yes| IS_READABLE{Is Readable?}
        
        IS_READABLE -->|No| NO_READ([Return permission_denied])
        IS_READABLE -->|Yes| GET_MEM[Get Memory]
        
        GET_MEM --> SET_CONFIG[Set in LTM Config]
        SET_CONFIG --> SAVE_MEM[Save Memory]
        SAVE_MEM --> SET_SUCCESS([Return Success])
    end
    
    subgraph "List Folder"
        LIST_START([list_folder called]) --> VALIDATE_TYPE[Validate Folder Type]
        VALIDATE_TYPE --> TYPE_OK{Valid Type?}
        
        TYPE_OK -->|No| INVALID_TYPE([Return validation_failed])
        TYPE_OK -->|Yes| SANITIZE[Sanitize Path]
        
        SANITIZE --> SAFE{Path Safe?}
        SAFE -->|No| TRAVERSAL([Return forbidden])
        SAFE -->|Yes| GET_MEM2[Get Memory]
        
        GET_MEM2 --> GET_CONFIG[Get Folder from Config]
        GET_CONFIG --> CONFIGURED{Folder Configured?}
        
        CONFIGURED -->|No| NOT_SET([Return folder_not_set])
        CONFIGURED -->|Yes| BUILD_TARGET[Build Target Path]
        
        BUILD_TARGET --> CHECK_SAFE[Check Path is Safe]
        CHECK_SAFE --> SAFE2{Within Base?}
        
        SAFE2 -->|No| FORBIDDEN([Return forbidden])
        SAFE2 -->|Yes| TARGET_EXISTS{Target Exists?}
        
        TARGET_EXISTS -->|No| NOT_FOUND([Return not_found])
        TARGET_EXISTS -->|Yes| TARGET_DIR{Is Directory?}
        
        TARGET_DIR -->|No| NOT_A_DIR([Return not_a_directory])
        TARGET_DIR -->|Yes| LIST_DIR[List Directory Contents]
        
        LIST_DIR --> LIST_OK{Permission OK?}
        LIST_OK -->|No| PERM_DENIED([Return permission_denied])
        LIST_OK -->|Yes| LIST_SUCCESS([Return Entries])
    end

8. LLM Communication Flow

flowchart TD
    subgraph "DeepSeek Client"
        DS_START([complete called]) --> DS_BUILD[Build Request Body]
        DS_BUILD --> DS_HEADERS[Set Headers with API Key]
        DS_HEADERS --> DS_POST[POST to DeepSeek API]
        DS_POST --> DS_OK{Response OK?}
        
        DS_OK -->|No| DS_ERR{Error Type?}
        DS_ERR -->|401| DS_AUTH([Raise LLMAuthenticationError])
        DS_ERR -->|429| DS_RATE([Raise LLMRateLimitError])
        DS_ERR -->|Other| DS_API([Raise LLMAPIError])
        
        DS_OK -->|Yes| DS_PARSE[Parse JSON Response]
        DS_PARSE --> DS_EXTRACT[Extract Content]
        DS_EXTRACT --> DS_RETURN([Return Content String])
    end
    
    subgraph "Ollama Client"
        OL_START([complete called]) --> OL_BUILD[Build Request Body]
        OL_BUILD --> OL_POST[POST to Ollama API]
        OL_POST --> OL_OK{Response OK?}
        
        OL_OK -->|No| OL_ERR([Raise LLMAPIError])
        OL_OK -->|Yes| OL_PARSE[Parse JSON Response]
        OL_PARSE --> OL_EXTRACT[Extract Message Content]
        OL_EXTRACT --> OL_RETURN([Return Content String])
    end

Legend

Symbol Meaning
([text]) Start/End (Terminal)
[text] Process
{text} Decision
/text/ Input/Output
--> Flow direction
-->|label| Conditional flow