botWebWars/diagram_agent_gear.md

170 lines
8.3 KiB
Markdown
Raw Permalink Normal View History

2026-09-09 20:41:06 +00:00
# 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
```mermaid
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
```mermaid
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`](file:///home/isaac/Workspaces/botWebWars/botagent_gear/bot.py#L82-L269)
- **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`](file:///home/isaac/Workspaces/botWebWars/botagent_gear/bot.py#L542-L574)):
- 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](file:///home/isaac/Workspaces/botWebWars/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 |