botWebWars/diagram_agent_gear.md

8.3 KiB
Raw Blame History

botagent_gear Architecture & Workflow Diagrams

This document outlines the system architecture, component relationships, and decision workflows of botagent_gear, the Google Cloud Vertex AI (Gemini) autonomous agent for botWebWars.


1. System Architecture Diagram

graph TB
    subgraph HostEnv["Environment & Configuration"]
        ENV["CLI Flags & Environment Variables<br/>(BOT_SERVER_URL, VERTEX_MODEL, etc.)"]
        AUTH_SRC["Auth Sources<br/>(ADC / gcloud / Service Account / API Key)"]
    end

    subgraph BotAgentGear["botagent_gear (bot.py)"]
        subgraph ClientLayer["LLM & Authentication Subsystem"]
            VGC["VertexGeminiClient<br/>Token cache, auth check, endpoint routing"]
            AUTH_RESOLV["Auth Resolver<br/>google.auth / gcloud CLI / API Key"]
            PROMPT_ENG["Prompt & Payload Builder<br/>System Instructions + JSON Schema Mode"]
            JSON_PARSE["extract_json<br/>Markdown stripping & JSON validation"]
        end

        subgraph CoreAgent["VertexAIBotAgent Subsystem"]
            RUN_LOOP["Turn Polling Loop<br/>GET /api/turn"]
            PERCEPTION["Perception Engine<br/>• Radar targets (distance, party, strength)<br/>• Available moves & diagonal squeeze cost<br/>• _build_local_map (17x17 ASCII minimap)"]
            
            subgraph StrategyEngine["Decision & Rules Engine"]
                ENCOUNTER["Encounter Evaluator<br/>_handle_adjacent_encounter"]
                RULES_GUARD["Mandatory Rules Enforcer<br/>(GAME_RULES.md: forced joins & battles)"]
                LLM_ALLIANCE["Voluntary Alliance Reasoner<br/>_decide_voluntary_alliance (Gemini)"]
                LLM_NAV["Tactical Navigation Reasoner<br/>_ask_llm_for_direction (Gemini)"]
                FALLBACK["Guardrail / Fallback Pathing<br/>Server recommended or nearest distance"]
            end
            
            ACTIONS["Action Dispatcher<br/>• Move bot (/move)<br/>• Form party (/parties)<br/>• Initiate battle (/battles/fight)<br/>• Pass turn (/pass)"]
        end
    end

    subgraph ExternalBackends["External Services"]
        SERVER["botWebWars Backend (FastAPI)<br/>Port 8000 REST API"]
        GEMINI["Google Vertex AI / AI Studio<br/>gemini-2.5-flash / gemini-3.8-flash"]
    end

    %% Wiring
    ENV --> CoreAgent
    AUTH_SRC --> AUTH_RESOLV
    AUTH_RESOLV --> VGC
    VGC --> PROMPT_ENG
    PROMPT_ENG --> GEMINI
    GEMINI --> JSON_PARSE
    JSON_PARSE --> VGC

    RUN_LOOP --> SERVER
    RUN_LOOP --> PERCEPTION
    PERCEPTION --> SERVER
    PERCEPTION --> StrategyEngine

    StrategyEngine --> VGC
    LLM_ALLIANCE -.-> VGC
    LLM_NAV -.-> VGC

    StrategyEngine --> ACTIONS
    RULES_GUARD --> ACTIONS
    FALLBACK --> ACTIONS
    ACTIONS --> SERVER

2. Turn Execution & Tactical Decision Flow

flowchart TD
    Start(["Turn Polled (bot's turn)"]) --> Refresh["refresh_status & fetch Radar Data"]
    Refresh --> CheckAdj{"Adjacent hostile / neutral<br/>target within distance <= 1?"}

    %% Adjacent Target Path
    CheckAdj -- Yes --> SoloCheck{"Is current bot Solo?"}
    
    SoloCheck -- "Yes (Solo)" --> TargetPartyCheck{"Is target in a Party?"}
    TargetPartyCheck -- "No (Target is Solo)" --> GeminiAlliance["Query Gemini via ask_json<br/>(Voluntary Alliance)"]
    GeminiAlliance --> AllianceChoice{"Form Alliance?"}
    AllianceChoice -- Yes --> FormParty["POST /api/parties<br/>(Higher strength leads)"]
    AllianceChoice -- No --> Pass1["POST /api/players/{id}/pass"]

    TargetPartyCheck -- "Yes (Target in Party)" --> CompareLeaderStr{"Bot Strength <= Target Leader Strength?"}
    CompareLeaderStr -- Yes --> JoinSquad["Move into squad<br/>(Voluntary absorption)"]
    CompareLeaderStr -- No --> FightParty["POST /api/battles/fight<br/>(Mandatory battle: refused weak leader)"]

    SoloCheck -- "No (In Party)" --> LeaderCheck{"Is bot the Party Leader?"}
    LeaderCheck -- No --> PassFollower["POST /api/players/{id}/pass<br/>(Follow leader command)"]
    LeaderCheck -- Yes --> PartyVsTarget{"Target has Party?"}
    PartyVsTarget -- Yes --> FightHostile["POST /api/battles/fight<br/>(Mandatory squad battle)"]
    PartyVsTarget -- No --> SoloTargetStr{"Solo target <= Leader Strength?"}
    SoloTargetStr -- Yes --> AbsorbSolo["Step toward target<br/>(Absorb solo follower)"]
    SoloTargetStr -- No --> FightSolo["POST /api/battles/fight<br/>(Mandatory battle: solo refused)"]

    %% Navigation Path
    CheckAdj -- No --> FetchMoves["Fetch available moves & Board snapshot"]
    FetchMoves --> GenMap["_build_local_map<br/>(Generate 17x17 ASCII minimap)"]
    GenMap --> AskNav["Query Gemini via ask_json<br/>(Direction & Reasoning)"]
    AskNav --> ValidChoice{"Chosen direction in legal moves?"}
    ValidChoice -- Yes --> ExecMove["POST /api/players/{id}/move"]
    ValidChoice -- No --> FallbackMove["Fallback: Server recommended or nearest distance"]
    FallbackMove --> ExecMove

    %% Outcome
    FormParty --> CheckEnd["Check Game Conclusion"]
    Pass1 --> CheckEnd
    JoinSquad --> CheckEnd
    FightParty --> CheckEnd
    PassFollower --> CheckEnd
    FightHostile --> CheckEnd
    AbsorbSolo --> CheckEnd
    FightSolo --> CheckEnd
    ExecMove --> CheckEnd
    CheckEnd --> Done(["End of Turn"])

3. Component Deep Dive

A. Authentication & LLM Client (VertexGeminiClient)

  • Module: bot.py
  • Multi-Auth Strategy:
    1. google-auth Python library using Application Default Credentials (ADC).
    2. gcloud CLI fallback via gcloud auth print-access-token.
    3. Direct OAuth token (VERTEX_ACCESS_TOKEN or GOOGLE_OAUTH_ACCESS_TOKEN).
    4. Service Account JSON key (GOOGLE_APPLICATION_CREDENTIALS).
    5. Direct Gemini API Key (GEMINI_API_KEY or VERTEX_API_KEY) routing to Google AI Studio.
  • Token Caching: Access tokens are cached for up to 50 minutes with automatic invalidation and single-retry on HTTP 401.
  • Structured JSON Mode: Uses generationConfig.responseMimeType = "application/json" with low temperature (0.3) for deterministic schema adherence.

B. Perception Engine & Spatial Representation

  • Minimap Generator (_build_local_map):
    • Generates a 17 × 17 ASCII grid centered on the bot (radius = 8).
    • Legend: @ = self, A = ally, E = enemy/neutral, M = mountain, F = forest, V = valley, # = boundary, . = open terrain.
  • Radar & Move Analysis:
    • Consumes /api/players/{id}/radar for target distance and party alignment.
    • Consumes /api/players/{id}/available-moves to account for diagonal obstacle squeeze penalties (-0.1 solo, -0.2 leader / -0.1 follower).

C. Hybrid Decision & Rules Engine

  • Deterministic Rules Enforcer:
    • Implements canonical rules from GAME_RULES.md.
    • Mandatory battles and joins bypass LLM invocation to guarantee engine compliance.
  • LLM Discretionary Invocations:
    • Voluntary Alliances: Solo bot meetings prompt Gemini to weigh party leadership vs. squad safety.
    • Tactical Navigation: Coordinates obstacle avoidance, frontier exploration, and hostile avoidance using the local minimap and radar summary.

4. Backend REST API Interactions

Method Endpoint Usage in botagent_gear
POST /api/players Register bot avatar or reconnect existing avatar
GET /api/players/{id} Refresh player health, score, and party leader status
GET /api/turn Turn polling loop to detect active player and round
GET /api/players/{id}/radar Scans surrounding bots and nearest target
GET /api/players/{id}/available-moves Evaluates passable directions & diagonal squeeze penalties
GET /api/board Full board snapshot for ASCII minimap generation
POST /api/players/{id}/move Execute cardinal / diagonal movement
POST /api/parties Establish voluntary alliance party
POST /api/battles/fight Initiate tactical 3-bout D20 confrontation
POST /api/players/{id}/pass Yield turn (follower wait or skipped turn)
GET /api/game/conclusion Check if single party remains (victory condition)
DELETE /api/players/{id} Clean disconnection on SIGINT / Ctrl+C