EZTIME2025 commited on
Commit
61ad06f
·
1 Parent(s): 6887a34

create plan and config

Browse files
.env.example ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================================================
2
+ # Environment Variables Template for PyCatan AI
3
+ # ============================================================================
4
+ # This file is a TEMPLATE - it will be committed to Git.
5
+ # Copy this file to .env and fill in your actual API keys.
6
+ #
7
+ # SETUP INSTRUCTIONS:
8
+ # 1. Copy this file: cp .env.example .env
9
+ # 2. Edit .env and paste your actual API keys
10
+ # 3. NEVER commit the .env file to Git!
11
+ # ============================================================================
12
+
13
+ # ----------------------------------------------------------------------------
14
+ # LLM API Keys
15
+ # ----------------------------------------------------------------------------
16
+ # Get your API keys from:
17
+ # - Gemini: https://aistudio.google.com/app/apikey
18
+ # - OpenAI: https://platform.openai.com/api-keys
19
+ # - Anthropic: https://console.anthropic.com/settings/keys
20
+
21
+ # Google Gemini API Key (recommended for development)
22
+ GEMINI_API_KEY=
23
+
24
+ # OpenAI API Key (optional)
25
+ OPENAI_API_KEY=
26
+
27
+ # Anthropic Claude API Key (optional)
28
+ ANTHROPIC_API_KEY=
29
+
30
+ # Azure OpenAI (optional)
31
+ AZURE_OPENAI_KEY=
32
+ AZURE_OPENAI_ENDPOINT=
33
+
34
+ # ----------------------------------------------------------------------------
35
+ # Optional: LLM Configuration Overrides
36
+ # ----------------------------------------------------------------------------
37
+ # You can override default settings via environment variables
38
+
39
+ # Default LLM provider (gemini, openai, anthropic, azure)
40
+ # DEFAULT_LLM_PROVIDER=gemini
41
+
42
+ # Default model name
43
+ # DEFAULT_MODEL_NAME=gemini-2.0-flash-exp
44
+
45
+ # Default temperature (0.0 to 2.0)
46
+ # DEFAULT_TEMPERATURE=0.7
47
+
48
+ # ----------------------------------------------------------------------------
49
+ # Development Settings
50
+ # ----------------------------------------------------------------------------
51
+
52
+ # Enable debug mode for detailed logging
53
+ # DEBUG_MODE=false
54
+
55
+ # Log directory
56
+ # LOG_DIRECTORY=logs/ai_agents
57
+
58
+ # ----------------------------------------------------------------------------
59
+ # Notes
60
+ # ----------------------------------------------------------------------------
61
+ # - The .env file is ignored by Git (see .gitignore)
62
+ # - Never share your .env file or commit it to version control
63
+ # - Keep your API keys secret and rotate them regularly
64
+ # - Each developer should have their own .env file with their own keys
65
+ # ============================================================================
.github/instructions/AI_AGENT_PRINCIPLES.md ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🎮 AI Agent Design Principles
2
+
3
+ **Date:** January 3, 2026
4
+ **Status:** 📋 In Planning
5
+
6
+ ## 🎯 Core Philosophy: "Give Tools and Let Go"
7
+
8
+ The AI agent architecture follows a **tool-based autonomy approach** where we provide the agent with:
9
+ - Rich game state context
10
+ - Available tools and actions
11
+ - Clear constraints and rules
12
+ - Memory management capabilities
13
+
14
+ Then we **let the agent play** - making its own decisions based on the context and available options.
15
+
16
+ ---
17
+
18
+ ## 🏗️ Architecture Principles
19
+
20
+ ### 1️⃣ Event-Driven LLM Invocation
21
+
22
+ The agent calls the LLM under specific scenarios:
23
+ - **Game Events**: Something happened in the game that affects the agent
24
+ - **Action Required**: The agent must make a decision (build, trade, play card, etc.)
25
+ - **Social Interaction**: Another player sent a message or made an offer
26
+ - **Turn Changes**: Beginning or end of turn phases
27
+
28
+ The agent doesn't continuously "think" - it responds to events and prompts.
29
+
30
+ ### 2️⃣ Self-Managed Memory
31
+
32
+ The agent maintains its own memory in a simple, accessible format:
33
+ - **Short-term memory**: Recent events and observations
34
+ - **Strategic notes**: Things to remember for future decisions
35
+ - **Social tracking**: Observations about other players' behavior
36
+ - **Game insights**: Patterns noticed during play
37
+
38
+ The memory structure is minimal but effective, allowing the agent to maintain context across turns.
39
+
40
+ ### 3️⃣ Generic and Configurable Design
41
+
42
+ The agent implementation should be:
43
+ - **Modular**: Easy to swap components or strategies
44
+ - **Configurable**: Support different play styles and behaviors
45
+ - **Extensible**: Simple to add new capabilities or tools
46
+ - **Reusable**: Same base agent class for different AI personalities
47
+
48
+ This allows experimentation with different AI approaches without rewriting core logic.
49
+
50
+ ### 4️⃣ Centralized Configuration
51
+
52
+ All critical parameters are managed in one place:
53
+ - **LLM Configuration**: Model selection, temperature, max tokens
54
+ - **API Credentials**: Keys and endpoints for LLM services
55
+ - **Agent Parameters**: Personality traits, risk tolerance, strategy preferences
56
+ - **Performance Settings**: Timeout limits, retry policies, caching options
57
+
58
+ This centralization simplifies tuning and experimentation.
59
+
60
+ ---
61
+
62
+ ## 📨 Prompt Processing Pipeline
63
+
64
+ ### Context Filtering and Preparation
65
+
66
+ Before sending prompts to the agent, game state undergoes processing:
67
+
68
+ 1. **Information Hiding**: Remove data the player shouldn't know
69
+ - Other players' cards and resources (unless revealed)
70
+ - Hidden development cards
71
+ - Future planned moves by other players
72
+
73
+ 2. **Perspective Adaptation**: Present information from agent's viewpoint
74
+ - "You received 1 Wood" instead of "Player Blue received 1 Wood"
75
+ - "Your resources" vs "Player resources"
76
+ - Relative positioning and strategic context
77
+
78
+ 3. **Custom Instructions**: Tailor prompts per agent instance
79
+ - Different personality instructions
80
+ - Unique strategic guidance
81
+ - Role-specific context
82
+
83
+ 4. **Context Enrichment**: Add relevant computed information
84
+ - Tile probabilities (based on dice numbers)
85
+ - Resource scarcity analysis
86
+ - Build opportunity assessment
87
+
88
+ ### Management Layer
89
+
90
+ A **prompt management layer** sits between GameManager and AI agents to:
91
+ - Transform raw game state into agent-specific context
92
+ - Filter and format information appropriately
93
+ - Handle simultaneous different messages to different agents
94
+ - Manage conversation history and memory updates
95
+
96
+ ---
97
+
98
+ ## 📋 Prompt Structure Principles
99
+
100
+ Based on the format in `promt_format.text`, prompts follow this structure:
101
+
102
+ ### Core Components:
103
+
104
+ 1. **Meta Data**: Agent identity and role
105
+ - Agent name/identifier
106
+ - Player color
107
+ - Personality or role description
108
+
109
+ 2. **Task Context**: Current situation
110
+ - What just happened in the game
111
+ - What action is now required
112
+ - Instructions for decision-making
113
+
114
+ 3. **Game State**: World information from agent perspective
115
+ - Agent's private information (resources, cards, points)
116
+ - Visible board state
117
+ - Other players' public information
118
+
119
+ 4. **Social Context**: Communication and relationships
120
+ - Recent chat messages
121
+ - Trade offers and negotiations
122
+ - Historical summaries of interactions
123
+
124
+ 5. **Memory**: Agent's self-maintained notes
125
+ - Strategic observations
126
+ - Plans and intentions
127
+ - Social dynamics tracking
128
+
129
+ 6. **Constraints**: Available actions and rules
130
+ - List of allowed actions at this moment
131
+ - Parameter structure for each action
132
+ - Usage instructions and examples
133
+
134
+ ### Flexibility Note:
135
+ While this structure provides a solid foundation, it should remain **adaptable**. Specific fields and formats may evolve as we test and refine the agent's performance.
136
+
137
+ ---
138
+
139
+ ## 🔄 Structured Response Format
140
+
141
+ The LLM response is **strictly structured** to enable programmatic processing:
142
+
143
+ ### Response Components:
144
+
145
+ 1. **Reasoning**: Agent's thought process (for debugging/logging)
146
+ - Current situation analysis
147
+ - Strategic considerations
148
+ - Decision rationale
149
+
150
+ 2. **Selected Action**: The chosen action with parameters
151
+ - Action type (BUILD_ROAD, OFFER_TRADE, etc.)
152
+ - Required parameters for that action
153
+ - Validation-ready format
154
+
155
+ 3. **Communication**: Optional message to other players
156
+ - Chat message content
157
+ - Target audience (all or specific player)
158
+
159
+ 4. **Memory Update**: What to remember for next time
160
+ - New notes to add
161
+ - Observations to store
162
+ - Strategy adjustments
163
+
164
+ ### Example Response Structure:
165
+ ```json
166
+ {
167
+ "reasoning": "I have enough resources for a settlement and node 23 gives me access to wheat...",
168
+ "action": {
169
+ "type": "BUILD_SETTLEMENT",
170
+ "parameters": {
171
+ "node_id": 23
172
+ }
173
+ },
174
+ "chat_message": "Building near the wheat fields!",
175
+ "memory_update": {
176
+ "add_note": "Focused on wheat production for development cards"
177
+ }
178
+ }
179
+ ```
180
+
181
+ This structured format allows the game loop to:
182
+ - Parse and validate the agent's decision
183
+ - Execute the action through GameManager
184
+ - Update agent memory automatically
185
+ - Continue the game flow seamlessly
186
+
187
+ ---
188
+
189
+ ## 🔧 Tool Integration
190
+
191
+ Agents have access to computational tools for enhanced decision-making:
192
+
193
+ - **Probability Calculator**: Dice roll probabilities for tiles
194
+ - **Resource Tracker**: Historical resource generation analysis
195
+ - **Path Finder**: Optimal road placement calculations
196
+ - **Trade Evaluator**: Fair trade assessment
197
+
198
+ **Tool Usage Limits**: To prevent excessive computation, agents are limited in tool calls per decision (e.g., maximum 3 tool executions).
199
+
200
+ ---
201
+
202
+ ## 🎭 Multi-Agent Considerations
203
+
204
+ When multiple AI agents play simultaneously:
205
+ - Each receives their own filtered game state
206
+ - Agents can negotiate with each other
207
+ - Social dynamics emerge naturally from LLM interactions
208
+ - No direct agent-to-agent communication (all goes through game system)
209
+
210
+ This creates emergent gameplay where AI strategies adapt to each other's behavior.
.github/instructions/WORK_PLAN.md ADDED
@@ -0,0 +1,484 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🗺️ AI Agent Development Work Plan
2
+
3
+ **Date:** January 3, 2026
4
+ **Status:** 📋 Planning Phase
5
+
6
+ ## 🎯 Project Goal
7
+
8
+ Build a fully functional LLM-based AI agent that can play Settlers of Catan autonomously, making intelligent strategic decisions and interacting naturally with other players.
9
+
10
+ ---
11
+
12
+ ## 📊 Development Phases
13
+
14
+ > **Note:** Phase 4 (Monitoring & Debugging) should be developed **early and in parallel** with Phase 3.
15
+ > The web dashboard and logging are **critical** for observing agent behavior during development!
16
+
17
+ ### Phase 1: Foundation & Infrastructure 🏗️
18
+ **Goal:** Build the core infrastructure needed to support AI agents
19
+
20
+ #### 1.1 Configuration Management
21
+ - [ ] Create centralized configuration system
22
+ - [ ] LLM settings (model, temperature, max_tokens, etc.)
23
+ - [ ] API credentials management
24
+ - [ ] Agent parameters (personality, risk tolerance, etc.)
25
+ - [ ] Performance settings (timeouts, retries, caching)
26
+ - [ ] Create config file format (YAML/JSON)
27
+ - [ ] Build configuration loader and validator
28
+ - [ ] Add environment variable support for sensitive data
29
+
30
+ **Files to create:**
31
+ - `pycatan/ai/config.py` - Configuration management
32
+ - `pycatan/ai/config_example.yaml` - Example configuration file
33
+
34
+ ---
35
+
36
+ #### 1.2 Prompt Management Layer
37
+ - [ ] Design prompt processing pipeline
38
+ - [ ] Implement game state filtering
39
+ - [ ] Hide opponent's private information
40
+ - [ ] Filter development cards
41
+ - [ ] Remove non-visible game elements
42
+ - [ ] Build perspective transformation
43
+ - [ ] Convert game state to agent's viewpoint
44
+ - [ ] Format resources and points
45
+ - [ ] Present relative positioning
46
+ - [ ] Create prompt template system
47
+ - [ ] Meta data section
48
+ - [ ] Task context section
49
+ - [ ] Game state section
50
+ - [ ] Social context section
51
+ - [ ] Memory section
52
+ - [ ] Constraints section
53
+ - [ ] Build custom instruction injection per agent
54
+
55
+ **Files to create:**
56
+ - `pycatan/ai/prompt_manager.py` - Main prompt processing
57
+ - `pycatan/ai/state_filter.py` - Game state filtering logic
58
+ - `pycatan/ai/prompt_templates.py` - Template definitions
59
+
60
+ ---
61
+
62
+ #### 1.3 Response Parser
63
+ - [ ] Define structured response format (JSON schema)
64
+ - [ ] Build response parser and validator
65
+ - [ ] Implement error handling for malformed responses
66
+ - [ ] Create fallback mechanisms for parsing failures
67
+ - [ ] Add response logging for debugging
68
+
69
+ **Files to create:**
70
+ - `pycatan/ai/response_parser.py` - Parse and validate LLM responses
71
+ - `pycatan/ai/schemas.py` - JSON schemas for requests/responses
72
+
73
+ ---
74
+
75
+ ### Phase 2: Memory System 🧠
76
+ **Goal:** Enable agents to maintain context and learning across turns
77
+
78
+ #### 2.1 Memory Structure
79
+ - [ ] Design memory data model
80
+ - [ ] Short-term observations (last N turns)
81
+ - [ ] Strategic notes (persistent)
82
+ - [ ] Social tracking (player relationships)
83
+ - [ ] Game insights (patterns observed)
84
+ - [ ] Implement memory storage (in-memory for now)
85
+ - [ ] Build memory retrieval and formatting
86
+
87
+ **Files to create:**
88
+ - `pycatan/ai/memory.py` - Memory management system
89
+
90
+ ---
91
+
92
+ #### 2.2 Memory Operations
93
+ - [ ] Add note creation and updates
94
+ - [ ] Implement memory pruning (keep relevant, remove old)
95
+ - [ ] Build memory summarization for context limits
96
+ - [ ] Create memory persistence (save/load between games)
97
+
98
+ ---
99
+
100
+ #### 2.3 Chat History Summarization ⚡
101
+ - [ ] Implement automatic chat summarization
102
+ - [ ] Configure separate smaller LLM for summarization (cost-effective)
103
+ - [ ] Monitor chat history length (e.g., last 10 messages)
104
+ - [ ] Trigger summarization when threshold reached
105
+ - [ ] Create summarization prompt template
106
+ - [ ] Build chat memory management
107
+ - [ ] Keep only most recent message after summarization
108
+ - [ ] Store summary in agent's memory
109
+ - [ ] Maintain summary history for context
110
+ - [ ] Add configuration for summarization settings
111
+ - [ ] Summarization model selection
112
+ - [ ] Message threshold for triggering
113
+ - [ ] Summary format and length
114
+
115
+ **Files to update:**
116
+ - `pycatan/ai/memory.py` - Add chat summarization logic
117
+ - `pycatan/ai/config.py` - Add summarization configuration
118
+ - `pycatan/ai/llm_client.py` - Support multiple models (main + summarization)
119
+
120
+ ---
121
+
122
+ ### Phase 3: Core AI Agent 🤖
123
+ **Goal:** Implement the main AI agent class
124
+
125
+ #### 3.1 Base Agent Implementation
126
+ - [ ] Create `AIAgent` class inheriting from `User`
127
+ - [ ] Implement required User interface methods
128
+ - [ ] `get_choice()` for decision-making
129
+ - [ ] Other interaction methods as needed
130
+ - [ ] Integrate with prompt manager
131
+ - [ ] Integrate with memory system
132
+ - [ ] Add agent state management
133
+
134
+ **Files to create:**
135
+ - `pycatan/players/ai_agent.py` - Main AI agent implementation (update existing stub)
136
+
137
+ ---
138
+
139
+ #### 3.2 LLM Integration
140
+ - [ ] Create LLM client abstraction
141
+ - [ ] Support for OpenAI API
142
+ - [ ] Support for Anthropic Claude
143
+ - [ ] Support for other providers (Azure, etc.)
144
+ - [ ] Implement API call handling
145
+ - [ ] Request formatting
146
+ - [ ] Response parsing
147
+ - [ ] Error handling and retries
148
+ - [ ] Rate limiting
149
+ - [ ] Add logging for all LLM interactions
150
+ - [ ] Implement cost tracking
151
+
152
+ **Files to create:**
153
+ - `pycatan/ai/llm_client.py` - LLM API abstraction
154
+ - `pycatan/ai/providers/` - Provider-specific implementations
155
+ - `openai_provider.py`
156
+ - `anthropic_provider.py`
157
+
158
+ ---
159
+
160
+ #### 3.3 Decision Pipeline
161
+ - [ ] Build event-to-prompt conversion
162
+ - [ ] Implement action extraction from responses
163
+ - [ ] Create action validation before execution
164
+ - [ ] Add decision logging and debugging
165
+ - [ ] Implement decision timeout handling
166
+
167
+ ---
168
+
169
+ ### Phase 4: Monitoring & Debugging Infrastructure 🔍
170
+ **Goal:** Build essential tools for observing and debugging agent behavior
171
+
172
+ **⚠️ CRITICAL: These tools are essential for development and must be built early!**
173
+
174
+ ---
175
+
176
+ #### 4.1 Web Dashboard for Real-Time Monitoring 🌐
177
+ **Priority: HIGH - Required before agent testing**
178
+
179
+ - [ ] Design web dashboard UI
180
+ - [ ] Multi-agent view (tabs or split screen per agent)
181
+ - [ ] Live prompt display with syntax highlighting
182
+ - [ ] Agent reasoning/thinking display
183
+ - [ ] Action selection visualization
184
+ - [ ] Chat window with all messages
185
+ - [ ] Game state summary panel
186
+ - [ ] Build backend API for dashboard
187
+ - [ ] WebSocket connection for live updates
188
+ - [ ] Endpoints for prompt/response history
189
+ - [ ] Agent state endpoints
190
+ - [ ] Chat history endpoint
191
+ - [ ] Implement prompt logging and streaming
192
+ - [ ] Capture all prompts sent to LLM
193
+ - [ ] Capture all responses from LLM
194
+ - [ ] Stream to dashboard in real-time
195
+ - [ ] Format for readability
196
+ - [ ] Build agent reasoning viewer
197
+ - [ ] Display internal_thinking/reasoning
198
+ - [ ] Show action selection process
199
+ - [ ] Highlight tool usage
200
+ - [ ] Show memory updates
201
+
202
+ **Files to create:**
203
+ - `pycatan/monitoring/` - NEW monitoring package
204
+ - `dashboard_server.py` - Flask/FastAPI server for dashboard
205
+ - `event_logger.py` - Captures and broadcasts events
206
+ - `prompt_tracker.py` - Tracks all LLM interactions
207
+ - `pycatan/monitoring/web/` - Dashboard frontend
208
+ - `index.html` - Main dashboard page
209
+ - `dashboard.js` - Dashboard functionality
210
+ - `dashboard.css` - Dashboard styling
211
+
212
+ ---
213
+
214
+ #### 4.2 Local Documentation & Logging 📁
215
+ **Priority: HIGH - Required for debugging**
216
+
217
+ - [ ] Design local documentation structure
218
+ - [ ] One folder per game session
219
+ - [ ] One file per agent with structured log
220
+ - [ ] Timestamp-based organization
221
+ - [ ] Implement per-agent documentation
222
+ - [ ] Agent configuration snapshot
223
+ - [ ] All prompts sent (formatted)
224
+ - [ ] All responses received (formatted)
225
+ - [ ] Decision timeline with reasoning
226
+ - [ ] Memory state snapshots
227
+ - [ ] Tool usage log
228
+ - [ ] Errors and warnings
229
+ - [ ] Build structured logging format
230
+ - [ ] JSON-based for easy parsing
231
+ - [ ] Markdown reports for human reading
232
+ - [ ] Searchable and filterable
233
+ - [ ] Add game session documentation
234
+ - [ ] Game state at each turn
235
+ - [ ] All chat messages with timestamps
236
+ - [ ] Final game results and statistics
237
+
238
+ **Files to create:**
239
+ - `pycatan/monitoring/local_logger.py` - Local file logging
240
+ - `pycatan/monitoring/session_recorder.py` - Game session recording
241
+ - `pycatan/monitoring/report_generator.py` - Generate readable reports
242
+
243
+ **Output structure:**
244
+ ```
245
+ logs/
246
+ └── game_sessions/
247
+ └── 2026-01-03_15-30-45/
248
+ ├── game_summary.json
249
+ ├── chat_log.txt
250
+ ├── agent_blue/
251
+ │ ├── config.json
252
+ │ ├── prompts.log
253
+ │ ├── decisions.log
254
+ │ └── memory_snapshots.json
255
+ ├── agent_red/
256
+ │ └── ...
257
+ └── agent_white/
258
+ └── ...
259
+ ```
260
+
261
+ ---
262
+
263
+ #### 4.3 Chat Management System 💬
264
+ **Priority: HIGH - Core game feature**
265
+
266
+ - [ ] Design chat system architecture
267
+ - [ ] Centralized chat manager
268
+ - [ ] Message routing between players
269
+ - [ ] Chat history per game
270
+ - [ ] Public vs private messages
271
+ - [ ] Implement chat manager component
272
+ - [ ] Message queue/buffer
273
+ - [ ] Broadcast to all players
274
+ - [ ] Direct messages between players
275
+ - [ ] Integration with GameManager
276
+ - [ ] Build chat observation interface
277
+ - [ ] Real-time chat display in web dashboard
278
+ - [ ] Chat log export
279
+ - [ ] Filter by sender/time
280
+ - [ ] Define chat protocol
281
+ - [ ] Message format (sender, content, timestamp, type)
282
+ - [ ] Chat commands (if any)
283
+ - [ ] Trade negotiation messages
284
+
285
+ **Files to create:**
286
+ - `pycatan/management/chat_manager.py` - Central chat management
287
+ - `pycatan/management/message.py` - Message data structure
288
+
289
+ **Integration points:**
290
+ - GameManager receives messages from players
291
+ - ChatManager distributes to other players and dashboard
292
+ - AI agents see messages in their prompt context
293
+ - Web dashboard shows live chat
294
+ - Local logs record all messages
295
+
296
+ ---
297
+
298
+ ### Phase 5: Tool System 🔧
299
+ **Goal:** Provide computational tools for agent decision-making
300
+
301
+ #### 5.1 Core Tools
302
+ - [ ] **Probability Calculator**
303
+ - [ ] Dice roll probabilities for tiles
304
+ - [ ] Expected resource generation rates
305
+ - [ ] Statistical analysis helpers
306
+ - [ ] **Resource Tracker**
307
+ - [ ] Historical resource generation
308
+ - [ ] Resource scarcity analysis
309
+ - [ ] Production trend analysis
310
+ - [ ] **Path Finder**
311
+ - [ ] Optimal road placement
312
+ - [ ] Longest road calculation
313
+ - [ ] Connectivity analysis
314
+ - [ ] **Trade Evaluator**
315
+ - [ ] Fair trade assessment
316
+ - [ ] Trade benefit calculation
317
+ - [ ] Market value estimation
318
+
319
+ **Files to create:**
320
+ - `pycatan/ai/tools/` - Tool implementations
321
+ - `probability_tool.py`
322
+ - `resource_tool.py`
323
+ - `pathfinding_tool.py`
324
+ - `trade_tool.py`
325
+ - `tool_manager.py` - Tool orchestration
326
+
327
+ ---
328
+
329
+ #### 5.2 Tool Integration
330
+ - [ ] Define tool interface/protocol
331
+ - [ ] Implement tool calling from prompts
332
+ - [ ] Add tool usage limits per decision
333
+ - [ ] Create tool result formatting
334
+ - [ ] Build tool usage logging
335
+
336
+ ---
337
+
338
+ ### Phase 6: Testing & Validation ✅
339
+ **Goal:** Ensure agent works correctly and plays reasonably
340
+
341
+ #### 6.1 Unit Tests
342
+ - [ ] Test prompt manager filtering
343
+ - [ ] Test response parser with various inputs
344
+ - [ ] Test memory operations
345
+ - [ ] Test each tool independently
346
+ - [ ] Test configuration loading
347
+
348
+ **Files to create:**
349
+ - `tests/unit/test_ai_agent.py`
350
+ - `tests/unit/test_prompt_manager.py`
351
+ - `tests/unit/test_memory.py`
352
+ - `tests/unit/test_tools.py`
353
+
354
+ ---
355
+
356
+ #### 6.2 Integration Tests
357
+ - [ ] Test agent in complete game loop
358
+ - [ ] Test agent vs human player
359
+ - [ ] Test multiple AI agents playing together
360
+ - [ ] Test edge cases and error scenarios
361
+ - [ ] Test long-running games (memory management)
362
+
363
+ **Files to create:**
364
+ - `tests/integration/test_ai_gameplay.py`
365
+ - `tests/integration/test_multi_agent.py`
366
+
367
+ ---
368
+
369
+ #### 6.3 Gameplay Validation
370
+ - [ ] Verify legal moves only
371
+ - [ ] Check strategic decision quality
372
+ - [ ] Evaluate social interaction naturalness
373
+ - [ ] Monitor LLM costs and performance
374
+ - [ ] Collect agent behavior metrics
375
+
376
+ ---
377
+
378
+ ### Phase 7: Optimization & Enhancement 🚀
379
+ **Goal:** Improve agent performance and capabilities
380
+
381
+ #### 7.1 Performance Optimization
382
+ - [ ] Reduce prompt token usage
383
+ - [ ] Implement response caching for similar situations
384
+ - [ ] Optimize tool execution
385
+ - [ ] Improve decision speed
386
+
387
+ ---
388
+
389
+ #### 7.2 Strategy Enhancement
390
+ - [ ] Tune agent personalities
391
+ - [ ] Improve opening game strategy
392
+ - [ ] Enhance mid-game adaptation
393
+ - [ ] Refine end-game tactics
394
+ - [ ] Better negotiation and trading
395
+
396
+ ---
397
+
398
+ #### 7.3 Advanced Features
399
+ - [ ] Multi-turn planning capability
400
+ - [ ] Opponent modeling
401
+ - [ ] Meta-strategy learning
402
+ - [ ] Tournament play support
403
+ - [ ] Statistical performance tracking
404
+
405
+ ---
406
+
407
+ ## 📁 Project Structure (Proposed)
408
+
409
+ ```
410
+ pycatan/
411
+ ├── ai/ # NEW: AI agent infrastructure
412
+ │ ├── __init__.py
413
+ │ ├── config.py # Configuration management
414
+ │ ├── prompt_manager.py # Prompt processing pipeline
415
+ │ ├── state_filter.py # Game state filtering
416
+ │ ├── prompt_templates.py # Prompt templates
417
+ │ ├── response_parser.py # Response parsing
418
+ │ ├── schemas.py # JSON schemas
419
+ │ ├── memory.py # Memory system + chat summarization
420
+ │ ├── llm_client.py # LLM abstraction (multi-model)
421
+ │ ├── providers/ # LLM provider implementations
422
+ │ │ ├── __init__.py
423
+ │ │ ├── openai_provider.py
424
+ │ │ └── anthropic_provider.py
425
+ │ └── tools/ # Agent tools
426
+ │ ├── __init__.py
427
+ │ ├── tool_manager.py
428
+ │ ├── probability_tool.py
429
+ │ ├── resource_tool.py
430
+ │ ├── pathfinding_tool.py
431
+ │ └── trade_tool.py
432
+ ├── monitoring/ # NEW: Monitoring & debugging
433
+ │ ├── __init__.py
434
+ │ ├── dashboard_server.py # Web dashboard backend
435
+ │ ├── event_logger.py # Event capture and broadcast
436
+ │ ├── prompt_tracker.py # LLM interaction tracking
437
+ │ ├── local_logger.py # Local file logging
438
+ │ ├── session_recorder.py # Game session recording
439
+ │ ├── report_generator.py # Report generation
440
+ │ └── web/ # Dashboard frontend
441
+ │ ├── index.html
442
+ │ ├── dashboard.js
443
+ │ └── dashboard.css
444
+ ├── management/
445
+ │ ├── actions.py # Existing
446
+ │ ├── game_manager.py # Existing
447
+ │ ├── log_events.py # Existing
448
+ │ ├── chat_manager.py # NEW: Chat management
449
+ │ └── message.py # NEW: Message data structure
450
+ ├── players/
451
+ │ ├── ai_agent.py # UPDATE: Full AI agent implementation
452
+ │ ├── human_user.py # Existing
453
+ │ └── user.py # Existing
454
+ └── ... # Existing structure
455
+
456
+ logs/ # NEW: Local documentation
457
+ └── game_sessions/
458
+ └── YYYY-MM-DD_HH-MM-SS/
459
+ ├── game_summary.json
460
+ ├── chat_log.txt
461
+ └── agent_<color>/
462
+ ├── config.json
463
+ ├── prompts.log
464
+ ├── decisions.log
465
+ └── memory_snapshots.json
466
+
467
+ examples/
468
+ ├── ai_testing/
469
+ │ ├── config_example.yaml # NEW: Example configuration
470
+ │ ├── test_single_agent.py # NEW: Test script
471
+ │ └── test_multi_agent.py # NEW: Multi-agent test
472
+ └── ...
473
+
474
+ tests/
475
+ ├── unit/
476
+ │ ├── test_ai_agent.py # NEW
477
+ │ ├── test_prompt_manager.py # NEW
478
+ │ ├── test_memory.py # NEW
479
+ │ └── test_tools.py # NEW
480
+ ├── integration/
481
+ │ ├── test_ai_gameplay.py # NEW
482
+ │ └── test_multi_agent.py # NEW
483
+ └── ...
484
+ ```
.github/instructions/updated.instructions.md ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ applyTo: '**'
3
+ ---
4
+
5
+ # PyCatan AI Project Instructions
6
+
7
+ ## 📋 Project Overview
8
+
9
+ **PyCatan_AI** is a Python implementation of the Settlers of Catan board game with a focus on AI agent development. The project consists of:
10
+
11
+ - **Core Game Engine**: Complete implementation of Catan game rules, board management, and resource mechanics
12
+ - **Game Management**: Turn-based coordination, action validation, and game state management
13
+ - **Player Types**: Support for both human players (CLI) and AI agents
14
+ - **Visualization**: Console and web-based game state visualization
15
+ - **AI Development**: Framework for building and testing LLM-based AI agents to play Catan
16
+
17
+ The primary goal is to create intelligent AI agents that can play Settlers of Catan autonomously, making strategic decisions about resource management, building placement, trading, and overall game strategy.
18
+
19
+ ## 📚 Related Documentation
20
+
21
+ For detailed information about specific aspects of the project, refer to:
22
+
23
+ - **[AI_ARCHITECTURE.md](.github/instructions/AI_ARCHITECTURE.md)** - Architecture and design of the AI agent system
24
+ - **[AI_AGENT_PRINCIPLES.md](.github/instructions/AI_AGENT_PRINCIPLES.md)** - Core design principles and philosophy for AI agent implementation
25
+ - **[WORK_PLAN.md](.github/instructions/WORK_PLAN.md)** - Detailed development work plan and roadmap
26
+ - *(Additional documentation files will be referenced here as they are created)*
27
+
28
+ ## 🎯 Project Context
29
+
30
+ This instruction file provides general coding guidelines and project context that AI assistants should follow when generating code, answering questions, or reviewing changes across the entire codebase.
.gitignore CHANGED
@@ -70,8 +70,38 @@ pip-selfcheck.json
70
 
71
  # Log files
72
  *.log
 
73
 
74
  # Temporary files
75
  *.tmp
76
  *.bak
77
  *~
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  # Log files
72
  *.log
73
+ logs/
74
 
75
  # Temporary files
76
  *.tmp
77
  *.bak
78
  *~
79
+
80
+ # ============================================================================
81
+ # AI Agent - Security and Privacy
82
+ # ============================================================================
83
+
84
+ # Environment variables with API keys (CRITICAL - NEVER COMMIT!)
85
+ .env
86
+ .env.local
87
+ .env.*.local
88
+
89
+ # AI Configuration files with sensitive data
90
+ # Note: *_example.yaml files WILL be committed as templates
91
+ pycatan/ai/*.yaml
92
+ !pycatan/ai/*_example.yaml
93
+ !pycatan/ai/*_example.yml
94
+ config.yaml
95
+ config.yml
96
+ *_config.yaml
97
+ *_config.yml
98
+
99
+ # AI Agent memory and game state files (may contain private data)
100
+ agent_memory.json
101
+ pycatan/ai/memory/*.json
102
+ logs/ai_agents/
103
+ logs/game_states/
104
+
105
+ # Test configuration files
106
+ test_config.yaml
107
+ test_*.yaml
QUICKSTART_API.md ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Quick Start - API Key Setup
2
+
3
+ ## 🚀 Fast Setup (2 minutes)
4
+
5
+ ### 1. Copy the template:
6
+ ```bash
7
+ copy .env.example .env
8
+ ```
9
+
10
+ ### 2. Get your Gemini API key:
11
+ - Go to: https://aistudio.google.com/app/apikey
12
+ - Click "Create API Key"
13
+ - Copy the key
14
+
15
+ ### 3. Edit `.env` file and paste your key:
16
+ ```
17
+ GEMINI_API_KEY=AIzaSyC_paste_your_key_here
18
+ ```
19
+
20
+ ### 4. Test it works:
21
+ ```bash
22
+ python examples/test_ai_config.py
23
+ ```
24
+
25
+ ## 📚 Full Documentation
26
+ See [docs/AI_SETUP.md](docs/AI_SETUP.md) for complete setup guide.
27
+
28
+ ## ✅ Security
29
+ - `.env` is NOT committed to Git (safe!)
30
+ - Only `.env.example` (template) is in Git
31
+ - Your API keys stay on your machine only
docs/AI_SETUP.md ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🤖 AI Agent Setup Guide
2
+
3
+ This guide explains how to set up and configure AI agents for PyCatan.
4
+
5
+ ## 📋 Table of Contents
6
+
7
+ 1. [Quick Start](#quick-start)
8
+ 2. [API Key Setup](#api-key-setup)
9
+ 3. [Configuration System](#configuration-system)
10
+ 4. [Security Best Practices](#security-best-practices)
11
+ 5. [Development Workflow](#development-workflow)
12
+
13
+ ---
14
+
15
+ ## 🚀 Quick Start
16
+
17
+ ### Step 1: Get an API Key
18
+
19
+ You need an API key from an LLM provider. We recommend **Google Gemini** for development:
20
+
21
+ 1. Go to [Google AI Studio](https://aistudio.google.com/app/apikey)
22
+ 2. Click "Create API Key"
23
+ 3. Copy your API key
24
+
25
+ **Other providers:**
26
+ - OpenAI: https://platform.openai.com/api-keys
27
+ - Anthropic: https://console.anthropic.com/settings/keys
28
+
29
+ ### Step 2: Setup Environment Variables
30
+
31
+ ```bash
32
+ # Copy the template file
33
+ cp .env.example .env
34
+
35
+ # Edit .env and paste your API key
36
+ # (Use any text editor)
37
+ ```
38
+
39
+ Example `.env` file:
40
+ ```bash
41
+ GEMINI_API_KEY=AIzaSyC_your_actual_api_key_here
42
+ ```
43
+
44
+ ### Step 3: Install Dependencies
45
+
46
+ ```bash
47
+ pip install pyyaml
48
+ ```
49
+
50
+ ### Step 4: Test the Configuration
51
+
52
+ ```bash
53
+ python examples/test_ai_config.py
54
+ ```
55
+
56
+ You should see:
57
+ ```
58
+ 🎉 All tests passed!
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 🔑 API Key Setup
64
+
65
+ ### Where API Keys Are Stored
66
+
67
+ **API keys are stored in the `.env` file**, which is:
68
+ - ✅ **NOT** committed to Git (protected by `.gitignore`)
69
+ - ✅ Stored locally on your machine only
70
+ - ✅ Easy to update without changing code
71
+
72
+ ### `.env` File Structure
73
+
74
+ ```bash
75
+ # .env - YOUR PRIVATE FILE (never commit this!)
76
+ GEMINI_API_KEY=your_actual_key_here
77
+ OPENAI_API_KEY=your_openai_key_here # Optional
78
+ ANTHROPIC_API_KEY=your_anthropic_key # Optional
79
+ ```
80
+
81
+ ### `.env.example` File
82
+
83
+ The **`.env.example`** file is a template that:
84
+ - ✅ **IS** committed to Git
85
+ - ✅ Shows what variables are needed
86
+ - ✅ Contains NO actual secrets
87
+ - ✅ Helps other developers know what to set up
88
+
89
+ **Never put real API keys in `.env.example`!**
90
+
91
+ ---
92
+
93
+ ## ⚙️ Configuration System
94
+
95
+ ### Overview
96
+
97
+ PyCatan uses a **two-file configuration system**:
98
+
99
+ ```
100
+ 📁 Project Root
101
+ ├── .env # ❌ NOT in Git - API keys
102
+ ├── .env.example # ✅ IN Git - Template
103
+ ├── pycatan/ai/
104
+ │ ├── config_example.yaml # ✅ IN Git - Documentation
105
+ │ ├── config_dev.yaml # ✅ IN Git - Dev defaults
106
+ │ └── my_agent_config.yaml # ❌ NOT in Git - Your custom config
107
+ ```
108
+
109
+ ### File Types Explained
110
+
111
+ #### 1. `.env` - Environment Variables (API Keys)
112
+ - **Purpose:** Store sensitive API keys
113
+ - **Git:** ❌ **NEVER** committed
114
+ - **Contains:** `GEMINI_API_KEY=actual_secret_key`
115
+ - **Who creates it:** Each developer on their machine
116
+
117
+ #### 2. `.env.example` - Environment Template
118
+ - **Purpose:** Template showing what variables are needed
119
+ - **Git:** ✅ Committed to Git
120
+ - **Contains:** `GEMINI_API_KEY=` (empty)
121
+ - **Who creates it:** Already created in the project
122
+
123
+ #### 3. `config_dev.yaml` - Development Defaults
124
+ - **Purpose:** Default configuration for development
125
+ - **Git:** ✅ Committed to Git
126
+ - **Contains:** All settings EXCEPT API keys
127
+ - **Who uses it:** Everyone, automatically
128
+
129
+ #### 4. `config_example.yaml` - Configuration Documentation
130
+ - **Purpose:** Complete documentation of all options
131
+ - **Git:** ✅ Committed to Git
132
+ - **Contains:** All possible settings with explanations
133
+ - **Who uses it:** Reference when creating custom configs
134
+
135
+ #### 5. Your Custom Config (e.g., `my_agent_config.yaml`)
136
+ - **Purpose:** Your personal agent configuration
137
+ - **Git:** ❌ NOT committed (optional)
138
+ - **Contains:** Custom personality, strategies, etc.
139
+ - **Who uses it:** You, when you want special behavior
140
+
141
+ ---
142
+
143
+ ## 🔒 Security Best Practices
144
+
145
+ ### ✅ DO:
146
+ - Keep your `.env` file local only
147
+ - Use different API keys for development and production
148
+ - Rotate your API keys regularly
149
+ - Review `.gitignore` to ensure `.env` is excluded
150
+ - Use `.env.example` as a template for team members
151
+
152
+ ### ❌ DON'T:
153
+ - Never commit `.env` to Git
154
+ - Never put API keys in configuration YAML files
155
+ - Never share your `.env` file
156
+ - Never hardcode API keys in Python code
157
+ - Never put API keys in commit messages or PR descriptions
158
+
159
+ ### Checking Security
160
+
161
+ ```bash
162
+ # Make sure .env is ignored by Git
163
+ git status
164
+
165
+ # .env should NOT appear in the list
166
+ # If it does, remove it:
167
+ git rm --cached .env
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 🛠️ Development Workflow
173
+
174
+ ### Using the Default Development Config
175
+
176
+ The simplest way - just use `config_dev.yaml`:
177
+
178
+ ```python
179
+ from pycatan.ai.config import AIConfig
180
+
181
+ # Loads config_dev.yaml by default
182
+ config = AIConfig.from_file('pycatan/ai/config_dev.yaml')
183
+
184
+ # API key is automatically loaded from .env
185
+ api_key = config.get_api_key() # Reads GEMINI_API_KEY from .env
186
+ ```
187
+
188
+ ### Creating a Custom Agent
189
+
190
+ 1. **Copy the example config:**
191
+ ```bash
192
+ cp pycatan/ai/config_example.yaml my_aggressive_agent.yaml
193
+ ```
194
+
195
+ 2. **Edit your config:**
196
+ ```yaml
197
+ agent_name: "Aggressive Trader"
198
+ agent:
199
+ personality: "aggressive"
200
+ risk_tolerance: 0.8
201
+ trade_willingness: 0.9
202
+ ```
203
+
204
+ 3. **Use it in your code:**
205
+ ```python
206
+ config = AIConfig.from_file('my_aggressive_agent.yaml')
207
+ ```
208
+
209
+ 4. **The API key is still loaded from `.env`** - you don't need to specify it!
210
+
211
+ ### Multiple Agents with Different Personalities
212
+
213
+ ```python
214
+ # Agent 1: Aggressive
215
+ config1 = AIConfig.from_file('configs/aggressive.yaml')
216
+
217
+ # Agent 2: Defensive
218
+ config2 = AIConfig.from_file('configs/defensive.yaml')
219
+
220
+ # Agent 3: Balanced (default)
221
+ config3 = AIConfig.from_file('pycatan/ai/config_dev.yaml')
222
+
223
+ # All three use the same API key from .env
224
+ ```
225
+
226
+ ---
227
+
228
+ ## 📝 Configuration Options
229
+
230
+ ### LLM Settings
231
+
232
+ ```yaml
233
+ llm:
234
+ provider: "gemini" # or "openai", "anthropic"
235
+ model_name: "gemini-2.0-flash-exp"
236
+ temperature: 0.7 # 0.0 = deterministic, 1.0 = creative
237
+ max_tokens: 4096
238
+ ```
239
+
240
+ ### Agent Personality
241
+
242
+ ```yaml
243
+ agent:
244
+ personality: "balanced" # aggressive, defensive, balanced, trading
245
+ risk_tolerance: 0.5 # 0.0 = safe, 1.0 = risky
246
+
247
+ # Strategic focus (0.0 to 1.0)
248
+ focus_on_settlements: 0.6
249
+ focus_on_cities: 0.7
250
+ focus_on_roads: 0.5
251
+ focus_on_dev_cards: 0.6
252
+
253
+ # Trading behavior
254
+ trade_willingness: 0.5 # 0.0 = never, 1.0 = always
255
+ trade_fairness: 0.7 # How fair are trades
256
+ ```
257
+
258
+ ### Debug Settings
259
+
260
+ ```yaml
261
+ debug:
262
+ debug_mode: true # Enable detailed logging
263
+ log_prompts: true # Log prompts sent to LLM
264
+ log_responses: true # Log LLM responses
265
+ save_game_states: true # Save states for analysis
266
+ ```
267
+
268
+ ---
269
+
270
+ ## 🧪 Testing Your Setup
271
+
272
+ ### Test 1: Check API Key
273
+
274
+ ```python
275
+ from pycatan.ai.config import AIConfig
276
+
277
+ config = AIConfig()
278
+ try:
279
+ api_key = config.get_api_key()
280
+ print("✓ API key loaded successfully")
281
+ except ValueError as e:
282
+ print(f"✗ Error: {e}")
283
+ ```
284
+
285
+ ### Test 2: Load Configuration
286
+
287
+ ```python
288
+ config = AIConfig.from_file('pycatan/ai/config_dev.yaml')
289
+ print(f"✓ Loaded config for: {config.agent_name}")
290
+ print(f" Provider: {config.llm.provider}")
291
+ print(f" Model: {config.llm.model_name}")
292
+ ```
293
+
294
+ ### Test 3: Run Full Test Suite
295
+
296
+ ```bash
297
+ python examples/test_ai_config.py
298
+ ```
299
+
300
+ ---
301
+
302
+ ## 🎯 Common Scenarios
303
+
304
+ ### Scenario 1: "I just cloned the repo"
305
+
306
+ 1. Create `.env`: `cp .env.example .env`
307
+ 2. Add your API key to `.env`
308
+ 3. Run tests: `python examples/test_ai_config.py`
309
+
310
+ ### Scenario 2: "I want to test different personalities"
311
+
312
+ Use the existing configs:
313
+ - `config_dev.yaml` - Balanced agent
314
+ - Or create custom configs based on `config_example.yaml`
315
+
316
+ ### Scenario 3: "I want to switch LLM providers"
317
+
318
+ Edit your config file:
319
+ ```yaml
320
+ llm:
321
+ provider: "openai"
322
+ model_name: "gpt-4-turbo-preview"
323
+ api_key_env_var: "OPENAI_API_KEY"
324
+ ```
325
+
326
+ Add the key to `.env`:
327
+ ```bash
328
+ OPENAI_API_KEY=sk-your-key-here
329
+ ```
330
+
331
+ ### Scenario 4: "My API key changed"
332
+
333
+ Just edit `.env` - no code changes needed!
334
+
335
+ ---
336
+
337
+ ## 📚 Next Steps
338
+
339
+ - Read [AI_ARCHITECTURE.md](AI_ARCHITECTURE.md) for system design
340
+ - Read [WORK_PLAN.md](WORK_PLAN.md) for development roadmap
341
+ - See [config_example.yaml](../pycatan/ai/config_example.yaml) for all options
342
+
343
+ ---
344
+
345
+ ## 🆘 Troubleshooting
346
+
347
+ ### "ModuleNotFoundError: No module named 'yaml'"
348
+ ```bash
349
+ pip install pyyaml
350
+ ```
351
+
352
+ ### "API key not found"
353
+ 1. Check `.env` exists in project root
354
+ 2. Check the API key variable name matches
355
+ 3. Try: `cat .env` to verify content
356
+
357
+ ### "Configuration file not found"
358
+ - Use absolute paths or run from project root
359
+ - Check file extension (`.yaml` not `.yml`)
360
+
361
+ ### "Still stuck?"
362
+ - Check [GitHub Issues](your-repo-url/issues)
363
+ - Review the test output: `python examples/test_ai_config.py`
364
+
365
+ ---
366
+
367
+ **Last Updated:** January 3, 2026
example_answer.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "internal_thinking": "I have 3 Sheep and 2 Wheat. I need Wood and Brick to build. I see Red asked for Sheep in the chat. My note says to trade with Red. I will offer him a deal verbally first to see if he accepts, before committing to a formal trade action. I won't pass turn yet.",
3
+
4
+ "note_to_self": "Waiting for Red's response. If he says yes, I will use OFFER_TRADE action next.",
5
+
6
+ "say_outloud": "Red, I have plenty of sheep. Can you give me 1 Wood and 1 Brick for 2 Sheep?",
7
+
8
+ "action": {
9
+ "type": "WAIT_FOR_RESPONSE",
10
+ "parameters": {}
11
+ }
12
+ }
examples/demo_ai_config.py ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Quick demo showing how the AI configuration system works.
3
+
4
+ This script demonstrates:
5
+ 1. How API keys are loaded from environment variables
6
+ 2. How to use config files
7
+ 3. The difference between config_example.yaml and config_dev.yaml
8
+ 4. How to create custom agent configurations
9
+ """
10
+
11
+ import os
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ # Add project root to path
16
+ project_root = Path(__file__).parent.parent
17
+ sys.path.insert(0, str(project_root))
18
+
19
+ from pycatan.ai.config import AIConfig, load_config
20
+
21
+
22
+ def demo_api_key_loading():
23
+ """Demo 1: How API keys are loaded from environment variables."""
24
+ print("\n" + "="*80)
25
+ print("DEMO 1: API Key Loading from Environment")
26
+ print("="*80)
27
+
28
+ print("\n1. API keys are stored in the .env file (NOT in Git)")
29
+ print(" Example .env file:")
30
+ print(" ┌─────────────────────────────────────┐")
31
+ print(" │ GEMINI_API_KEY=AIzaSyC...your_key │")
32
+ print(" │ OPENAI_API_KEY=sk-...your_key │")
33
+ print(" └─────────────────────────────────────┘")
34
+
35
+ print("\n2. The config system reads from environment variables:")
36
+ config = AIConfig()
37
+
38
+ print(f" Provider: {config.llm.provider}")
39
+ print(f" Env var name: {config.llm.api_key_env_var}")
40
+
41
+ # Try to get API key
42
+ try:
43
+ api_key = config.get_api_key()
44
+ # Hide most of the key for security
45
+ masked_key = api_key[:10] + "..." + api_key[-4:] if len(api_key) > 14 else "***"
46
+ print(f" ✓ API key loaded: {masked_key}")
47
+ print(f" ✓ Full length: {len(api_key)} characters")
48
+ except ValueError as e:
49
+ print(f" ✗ No API key found: {e}")
50
+ print("\n 👉 To fix this:")
51
+ print(" 1. Copy .env.example to .env")
52
+ print(" 2. Add your API key to .env")
53
+ print(" 3. The .env file will NOT be committed to Git")
54
+
55
+
56
+ def demo_config_files():
57
+ """Demo 2: Different types of config files."""
58
+ print("\n" + "="*80)
59
+ print("DEMO 2: Configuration Files Explained")
60
+ print("="*80)
61
+
62
+ print("\n📁 THREE types of config files:")
63
+
64
+ print("\n1️⃣ config_example.yaml - DOCUMENTATION")
65
+ print(" ├─ Purpose: Shows ALL possible settings with explanations")
66
+ print(" ├─ Git: ✅ Committed (it's documentation)")
67
+ print(" ├─ Usage: Read it to understand options")
68
+ print(" └─ Don't use directly - copy and customize it")
69
+
70
+ print("\n2️⃣ config_dev.yaml - DEFAULT FOR DEVELOPMENT")
71
+ print(" ├─ Purpose: Ready-to-use config for development")
72
+ print(" ├─ Git: ✅ Committed (team shares same defaults)")
73
+ print(" ├─ Usage: Just load it and start coding!")
74
+ print(" └─ Example: AIConfig.from_file('pycatan/ai/config_dev.yaml')")
75
+
76
+ print("\n3️⃣ your_custom_config.yaml - YOUR PERSONAL AGENT")
77
+ print(" ├─ Purpose: Your custom agent configuration")
78
+ print(" ├─ Git: ❌ NOT committed (optional)")
79
+ print(" ├─ Usage: Create when you want custom behavior")
80
+ print(" └─ Example: Copy config_example.yaml and modify")
81
+
82
+ print("\n💡 WORKFLOW:")
83
+ print(" • During development: Use config_dev.yaml")
84
+ print(" • Want custom agent: Copy config_example.yaml → my_agent.yaml")
85
+ print(" • API keys: Always in .env (never in YAML files)")
86
+
87
+
88
+ def demo_default_config():
89
+ """Demo 3: Using the default development config."""
90
+ print("\n" + "="*80)
91
+ print("DEMO 3: Using the Default Development Config")
92
+ print("="*80)
93
+
94
+ print("\n▶ Loading config_dev.yaml...")
95
+ config_path = project_root / "pycatan" / "ai" / "config_dev.yaml"
96
+
97
+ if config_path.exists():
98
+ config = AIConfig.from_file(str(config_path))
99
+
100
+ print(f"\n✓ Loaded successfully!")
101
+ print(f"\n📋 Configuration Details:")
102
+ print(f" Agent Name: {config.agent_name}")
103
+ print(f" Provider: {config.llm.provider}")
104
+ print(f" Model: {config.llm.model_name}")
105
+ print(f" Temperature: {config.llm.temperature}")
106
+ print(f" Personality: {config.agent.personality}")
107
+ print(f" Risk Tolerance: {config.agent.risk_tolerance}")
108
+ print(f" Debug Mode: {config.debug.debug_mode}")
109
+
110
+ print(f"\n⚙️ Strategic Focus:")
111
+ print(f" Settlements: {config.agent.focus_on_settlements}")
112
+ print(f" Cities: {config.agent.focus_on_cities}")
113
+ print(f" Roads: {config.agent.focus_on_roads}")
114
+ print(f" Dev Cards: {config.agent.focus_on_dev_cards}")
115
+
116
+ print(f"\n💬 Social Behavior:")
117
+ print(f" Trade Willingness: {config.agent.trade_willingness}")
118
+ print(f" Chat Frequency: {config.agent.chat_frequency}")
119
+ print(f" Chattiness: {config.agent.chattiness}")
120
+ else:
121
+ print(f"✗ Config file not found: {config_path}")
122
+
123
+
124
+ def demo_custom_config():
125
+ """Demo 4: Creating a custom agent configuration."""
126
+ print("\n" + "="*80)
127
+ print("DEMO 4: Creating Custom Agent Configuration")
128
+ print("="*80)
129
+
130
+ print("\n▶ Creating an 'Aggressive Trader' agent...")
131
+
132
+ # Start with default config
133
+ config = AIConfig()
134
+
135
+ # Customize for aggressive trading
136
+ config.agent_name = "Aggressive Trader"
137
+ config.agent.personality = "trading"
138
+ config.agent.risk_tolerance = 0.8 # High risk
139
+ config.agent.trade_willingness = 0.9 # Trades a lot
140
+ config.agent.trade_fairness = 0.6 # Slightly unfair trades
141
+ config.agent.focus_on_settlements = 0.8 # Expand quickly
142
+ config.agent.chat_frequency = 0.7 # Very chatty
143
+ config.agent.chattiness = "chatty"
144
+ config.llm.temperature = 0.8 # More creative
145
+
146
+ print("\n✓ Custom config created!")
147
+ print(f"\n📋 Agent Profile:")
148
+ print(f" Name: {config.agent_name}")
149
+ print(f" Personality: {config.agent.personality}")
150
+ print(f" Risk Tolerance: {config.agent.risk_tolerance} (HIGH)")
151
+ print(f" Trade Willingness: {config.agent.trade_willingness} (VERY HIGH)")
152
+ print(f" Trade Fairness: {config.agent.trade_fairness} (Slightly unfair)")
153
+ print(f" Chattiness: {config.agent.chattiness}")
154
+ print(f" Temperature: {config.llm.temperature} (Creative)")
155
+
156
+ # Save to file
157
+ custom_file = project_root / "aggressive_trader_config.yaml"
158
+ config.to_file(str(custom_file))
159
+ print(f"\n💾 Saved to: {custom_file.name}")
160
+ print(" (This file will NOT be committed to Git)")
161
+
162
+ # Clean up
163
+ custom_file.unlink()
164
+ print(" (Cleaned up demo file)")
165
+
166
+
167
+ def demo_security():
168
+ """Demo 5: Security features."""
169
+ print("\n" + "="*80)
170
+ print("DEMO 5: Security Features")
171
+ print("="*80)
172
+
173
+ print("\n🔒 What's Protected:")
174
+ print(" ✅ .env file → NOT in Git")
175
+ print(" ✅ Your custom *.yaml configs → NOT in Git")
176
+ print(" ✅ Agent memory files → NOT in Git")
177
+ print(" ✅ Game state logs → NOT in Git")
178
+
179
+ print("\n📤 What's Committed:")
180
+ print(" ✅ .env.example → Template (no secrets)")
181
+ print(" ✅ config_example.yaml → Documentation")
182
+ print(" ✅ config_dev.yaml → Default settings")
183
+ print(" ✅ Python code → No secrets in code")
184
+
185
+ print("\n⚠️ Remember:")
186
+ print(" • NEVER commit your .env file")
187
+ print(" • NEVER put API keys in YAML files")
188
+ print(" • NEVER hardcode API keys in Python code")
189
+ print(" • Each developer has their own .env file")
190
+
191
+
192
+ def main():
193
+ """Run all demos."""
194
+ print("\n" + "="*80)
195
+ print("🎓 AI CONFIGURATION SYSTEM - INTERACTIVE DEMO")
196
+ print("="*80)
197
+ print("\nThis demo explains how the configuration system works")
198
+ print("and shows you the difference between the config files.")
199
+
200
+ demo_api_key_loading()
201
+ demo_config_files()
202
+ demo_default_config()
203
+ demo_custom_config()
204
+ demo_security()
205
+
206
+ print("\n" + "="*80)
207
+ print("✅ DEMO COMPLETE!")
208
+ print("="*80)
209
+ print("\n📚 Next Steps:")
210
+ print(" 1. Read: docs/AI_SETUP.md (complete setup guide)")
211
+ print(" 2. Read: QUICKSTART_API.md (2-minute setup)")
212
+ print(" 3. Look at: pycatan/ai/config_example.yaml (all options)")
213
+ print(" 4. Use: pycatan/ai/config_dev.yaml (start coding!)")
214
+ print("\n💡 Quick Start:")
215
+ print(" from pycatan.ai.config import AIConfig")
216
+ print(" config = AIConfig.from_file('pycatan/ai/config_dev.yaml')")
217
+ print(" api_key = config.get_api_key() # From .env file")
218
+ print("\n" + "="*80)
219
+
220
+
221
+ if __name__ == "__main__":
222
+ main()
examples/test_ai_config.py ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Test script for AI Configuration System
3
+
4
+ This script tests the configuration management functionality:
5
+ 1. Create default configuration
6
+ 2. Save to file
7
+ 3. Load from file
8
+ 4. Validate configuration
9
+ 5. Test different personalities
10
+ """
11
+
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ # Add project root to path
16
+ project_root = Path(__file__).parent.parent
17
+ sys.path.insert(0, str(project_root))
18
+
19
+ from pycatan.ai.config import AIConfig, load_config
20
+
21
+
22
+ def test_default_config():
23
+ """Test creating and using default configuration."""
24
+ print("\n" + "="*80)
25
+ print("TEST 1: Default Configuration")
26
+ print("="*80)
27
+
28
+ config = AIConfig()
29
+ print(f"\n✓ Created default config:\n{config}")
30
+
31
+ # Validate
32
+ try:
33
+ config.validate()
34
+ print("✓ Configuration is valid")
35
+ except ValueError as e:
36
+ print(f"✗ Validation failed: {e}")
37
+ return False
38
+
39
+ return True
40
+
41
+
42
+ def test_save_and_load():
43
+ """Test saving and loading configuration."""
44
+ print("\n" + "="*80)
45
+ print("TEST 2: Save and Load Configuration")
46
+ print("="*80)
47
+
48
+ # Create custom config
49
+ config = AIConfig()
50
+ config.agent_name = "Test Agent"
51
+ config.agent.personality = "aggressive"
52
+ config.agent.risk_tolerance = 0.8
53
+ config.llm.temperature = 0.9
54
+
55
+ # Save to file
56
+ test_file = "test_config.yaml"
57
+ config.to_file(test_file)
58
+ print(f"✓ Saved configuration to {test_file}")
59
+
60
+ # Load from file
61
+ loaded_config = AIConfig.from_file(test_file)
62
+ print(f"✓ Loaded configuration from {test_file}")
63
+
64
+ # Verify values
65
+ assert loaded_config.agent_name == "Test Agent", "Agent name mismatch"
66
+ assert loaded_config.agent.personality == "aggressive", "Personality mismatch"
67
+ assert loaded_config.agent.risk_tolerance == 0.8, "Risk tolerance mismatch"
68
+ assert loaded_config.llm.temperature == 0.9, "Temperature mismatch"
69
+
70
+ print("✓ All values match correctly")
71
+
72
+ # Clean up
73
+ Path(test_file).unlink()
74
+ print(f"✓ Cleaned up {test_file}")
75
+
76
+ return True
77
+
78
+
79
+ def test_personalities():
80
+ """Test creating configs with different personalities."""
81
+ print("\n" + "="*80)
82
+ print("TEST 3: Different Personalities")
83
+ print("="*80)
84
+
85
+ personalities = {
86
+ "aggressive": {
87
+ "personality": "aggressive",
88
+ "risk_tolerance": 0.8,
89
+ "trade_willingness": 0.7,
90
+ "focus_on_settlements": 0.8
91
+ },
92
+ "defensive": {
93
+ "personality": "defensive",
94
+ "risk_tolerance": 0.3,
95
+ "trade_willingness": 0.3,
96
+ "focus_on_cities": 0.9
97
+ },
98
+ "balanced": {
99
+ "personality": "balanced",
100
+ "risk_tolerance": 0.5,
101
+ "trade_willingness": 0.5
102
+ },
103
+ "trading": {
104
+ "personality": "trading",
105
+ "risk_tolerance": 0.6,
106
+ "trade_willingness": 0.9,
107
+ "chat_frequency": 0.7
108
+ }
109
+ }
110
+
111
+ for name, settings in personalities.items():
112
+ config = AIConfig()
113
+ config.agent_name = f"{name.capitalize()} Agent"
114
+
115
+ # Apply settings
116
+ for key, value in settings.items():
117
+ setattr(config.agent, key, value)
118
+
119
+ # Validate
120
+ config.validate()
121
+ print(f"✓ Created and validated '{name}' personality")
122
+ print(f" - Risk tolerance: {config.agent.risk_tolerance}")
123
+ print(f" - Trade willingness: {config.agent.trade_willingness}")
124
+
125
+ return True
126
+
127
+
128
+ def test_validation():
129
+ """Test configuration validation."""
130
+ print("\n" + "="*80)
131
+ print("TEST 4: Configuration Validation")
132
+ print("="*80)
133
+
134
+ # Test invalid temperature
135
+ config = AIConfig()
136
+ config.llm.temperature = 3.0 # Invalid (> 2.0)
137
+
138
+ try:
139
+ config.validate()
140
+ print("✗ Should have caught invalid temperature")
141
+ return False
142
+ except ValueError as e:
143
+ print(f"✓ Correctly caught invalid temperature: {e}")
144
+
145
+ # Test invalid risk tolerance
146
+ config = AIConfig()
147
+ config.agent.risk_tolerance = 1.5 # Invalid (> 1.0)
148
+
149
+ try:
150
+ config.validate()
151
+ print("✗ Should have caught invalid risk_tolerance")
152
+ return False
153
+ except ValueError as e:
154
+ print(f"✓ Correctly caught invalid risk_tolerance: {e}")
155
+
156
+ # Test valid config
157
+ config = AIConfig()
158
+ config.validate()
159
+ print("✓ Valid configuration passes validation")
160
+
161
+ return True
162
+
163
+
164
+ def test_to_dict_and_back():
165
+ """Test dictionary conversion."""
166
+ print("\n" + "="*80)
167
+ print("TEST 5: Dictionary Conversion")
168
+ print("="*80)
169
+
170
+ # Create config
171
+ config = AIConfig()
172
+ config.agent_name = "Dict Test Agent"
173
+ config.agent.personality = "trading"
174
+ config.llm.temperature = 0.8
175
+
176
+ # Convert to dict
177
+ config_dict = config.to_dict()
178
+ print("✓ Converted config to dictionary")
179
+
180
+ # Create from dict
181
+ new_config = AIConfig.from_dict(config_dict)
182
+ print("✓ Created config from dictionary")
183
+
184
+ # Verify values
185
+ assert new_config.agent_name == config.agent_name
186
+ assert new_config.agent.personality == config.agent.personality
187
+ assert new_config.llm.temperature == config.llm.temperature
188
+ print("✓ All values preserved correctly")
189
+
190
+ return True
191
+
192
+
193
+ def main():
194
+ """Run all tests."""
195
+ print("\n" + "="*80)
196
+ print("AI CONFIGURATION SYSTEM - TEST SUITE")
197
+ print("="*80)
198
+
199
+ tests = [
200
+ ("Default Configuration", test_default_config),
201
+ ("Save and Load", test_save_and_load),
202
+ ("Different Personalities", test_personalities),
203
+ ("Validation", test_validation),
204
+ ("Dictionary Conversion", test_to_dict_and_back)
205
+ ]
206
+
207
+ results = []
208
+ for name, test_func in tests:
209
+ try:
210
+ result = test_func()
211
+ results.append((name, result))
212
+ except Exception as e:
213
+ print(f"\n✗ Test '{name}' failed with exception: {e}")
214
+ import traceback
215
+ traceback.print_exc()
216
+ results.append((name, False))
217
+
218
+ # Summary
219
+ print("\n" + "="*80)
220
+ print("TEST SUMMARY")
221
+ print("="*80)
222
+
223
+ passed = sum(1 for _, result in results if result)
224
+ total = len(results)
225
+
226
+ for name, result in results:
227
+ status = "✓ PASS" if result else "✗ FAIL"
228
+ print(f"{status}: {name}")
229
+
230
+ print(f"\nTotal: {passed}/{total} tests passed")
231
+
232
+ if passed == total:
233
+ print("\n🎉 All tests passed!")
234
+ return 0
235
+ else:
236
+ print(f"\n❌ {total - passed} test(s) failed")
237
+ return 1
238
+
239
+
240
+ if __name__ == "__main__":
241
+ sys.exit(main())
promt_format.text ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // מידע על זהות השחקן
3
+ "meta_data": {
4
+ "agent_name": "Dani",
5
+ "my_color": "Blue",
6
+ "role": "You are a pro Catan player.",
7
+ },
8
+ // מידע על מה קרה עכשיו בעולם
9
+ "task_context": {
10
+ "what_just_happened": "Player 'Red' rolled a 6. You received 1 Wood.",
11
+ "instructions": "Analyze the game state and select the optimal move from 'allowed_actions'. You may use the provided tools to gather more data (e.g., calculate probabilities), but limit yourself to a maximum of 3 tool executions per decision. If you wish to negotiate or wait for other players, select the 'WAIT_FOR_RESPONSE' action.",
12
+ },
13
+ // קונטקסט על הSTATE של העולם מותאם לנקודת המבט של השחקן
14
+ "game_state": {
15
+ "my_private_info": {
16
+ "resources": {"wood": 0, "brick": 0, "sheep": 3, "wheat": 1, "ore": 0},
17
+ "development_cards": [],
18
+ "victory_points": 2
19
+ },....
20
+ },
21
+
22
+ "social_context": {
23
+ // ההודעות האחרונות בצאט
24
+ "recent_chat": [
25
+ {"sender": "Red", "content": "I need sheep desperately."}
26
+ ],
27
+
28
+ "last_summaries": [1: "Dana is off to a quick start with a lucky roll and a trade with Alex to build toward the wood port. I’ve warned the table about her strategy, but she’s already trying to downplay her early advantage.",2: "I’m frustrated by the lack of 8s and Dana’s blatant betrayal after she snubbed my brick trade for a secret deal with Alex. It seems those two are continuing to work together to dominate the game despite my warnings to the table."]
29
+ },
30
+
31
+ "memory": {
32
+ // דברים שאני רוצה לזכור להמשך
33
+ "notes_for_myself": [1 : "My plan is to trade Sheep for Wood with Red to build a settlement." , 2: "shani been an ashole to me"]
34
+ },
35
+
36
+ "constraints": {
37
+ "usage_instructions": "Choose one action type from the list below. Populate the 'parameters' field in your response strictly according to the 'example_parameters' structure provided.",
38
+
39
+ "allowed_actions": [
40
+ {
41
+ "type": "BUILD_ROAD",
42
+ "description": "Build a road on a specific edge ID.",
43
+ "example_parameters": { "edge_id": 12 }
44
+ },
45
+ {
46
+ "type": "BUILD_SETTLEMENT",
47
+ "description": "Build a settlement on a specific node ID.",
48
+ "example_parameters": { "node_id": 45 }
49
+ },
50
+ {
51
+ "type": "BUILD_CITY",
52
+ "description": "Upgrade an existing settlement to a city.",
53
+ "example_parameters": { "node_id": 45 }
54
+ },
55
+ {
56
+ "type": "OFFER_TRADE",
57
+ "description": "Propose a trade to all players or a specific one.",
58
+ "example_parameters": {
59
+ "give": {"wood": 1, "sheep": 1},
60
+ "receive": {"ore": 1},
61
+ "target_player_color": "Red" // Optional, remove key for public offer
62
+ }
63
+ },
64
+ {
65
+ "type": "PLAY_DEV_CARD",
66
+ "description": "Play a development card. Specific params depend on the card.",
67
+ "example_parameters": [
68
+ { "card": "KNIGHT", "robber_hex": 7, "target_victim": "Red" },
69
+ { "card": "MONOPOLY", "resource": "sheep" },
70
+ { "card": "YEAR_OF_PLENTY", "resources": ["wood", "brick"] },
71
+ { "card": "ROAD_BUILDING", "edges": [12, 13] }
72
+ ]
73
+ },
74
+ {
75
+ "type": "WAIT_FOR_RESPONSE",
76
+ "description": "Do nothing on the board, just chat or wait.",
77
+ "example_parameters": {}
78
+ },
79
+ {
80
+ "type": "END_TURN",
81
+ "description": "Pass the dice to the next player.",
82
+ "example_parameters": {}
83
+ }
84
+ ]
85
+ }
86
+ }
pycatan/ai/__init__.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AI Agent Infrastructure for PyCatan
3
+
4
+ This package contains the infrastructure for building LLM-based AI agents
5
+ that can play Settlers of Catan autonomously.
6
+
7
+ Components:
8
+ - config: Configuration management for AI agents
9
+ - prompt_manager: Prompt construction and game state filtering
10
+ - response_parser: LLM response parsing and validation
11
+ - memory: Agent memory and learning systems
12
+ - llm_client: LLM API abstraction and client
13
+
14
+ Architecture Overview:
15
+ ┌─────────────────────────────────────────────────────────┐
16
+ │ AIAgent │
17
+ │ (Main AI player implementation) │
18
+ ├─────────────────────────────────────────────────────────┤
19
+ │ │
20
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
21
+ │ │ Config │ │ Prompt │ │ Response │ │
22
+ │ │ Management │ │ Manager │ │ Parser │ │
23
+ │ └──────────────┘ └──────────────┘ └──────────────┘ │
24
+ │ │
25
+ │ ┌──────────────┐ ┌──────────────┐ │
26
+ │ │ Memory │ │ LLM Client │ │
27
+ │ │ System │ │ (Multi-API) │ │
28
+ │ └──────────────┘ └──────────────┘ │
29
+ │ │
30
+ └─────────────────────────────────────────────────────────┘
31
+ """
32
+
33
+ __version__ = "0.1.0"
34
+ __all__ = ["config"]
pycatan/ai/config.py ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Configuration Management for AI Agents
3
+
4
+ This module provides centralized configuration management for AI agents,
5
+ including LLM settings, API credentials, agent parameters, and performance settings.
6
+
7
+ Features:
8
+ - Load configuration from YAML files
9
+ - Environment variable support for sensitive data
10
+ - Configuration validation
11
+ - Default values with override capability
12
+ - Multiple LLM provider support
13
+
14
+ Usage:
15
+ from pycatan.ai.config import AIConfig
16
+
17
+ # Load from file
18
+ config = AIConfig.from_file('my_agent_config.yaml')
19
+
20
+ # Or create with defaults
21
+ config = AIConfig()
22
+
23
+ # Access settings
24
+ model = config.llm.model_name
25
+ temperature = config.llm.temperature
26
+ api_key = config.get_api_key()
27
+ """
28
+
29
+ import os
30
+ import yaml
31
+ from typing import Dict, Any, Optional
32
+ from dataclasses import dataclass, field, asdict
33
+ from pathlib import Path
34
+
35
+
36
+ @dataclass
37
+ class LLMConfig:
38
+ """Configuration for LLM provider and model settings."""
39
+
40
+ # Provider settings
41
+ provider: str = "gemini" # "gemini", "openai", "anthropic", "azure"
42
+ model_name: str = "gemini-2.0-flash-exp"
43
+
44
+ # Generation parameters
45
+ temperature: float = 0.7
46
+ max_tokens: int = 4096
47
+ top_p: float = 0.95
48
+ top_k: int = 40
49
+
50
+ # API settings
51
+ api_key_env_var: str = "GEMINI_API_KEY" # Environment variable name
52
+ api_base_url: Optional[str] = None # For custom endpoints
53
+
54
+ # Performance
55
+ timeout_seconds: int = 30
56
+ max_retries: int = 3
57
+ retry_delay_seconds: float = 1.0
58
+
59
+ # Cost tracking
60
+ track_usage: bool = True
61
+ log_requests: bool = True
62
+
63
+
64
+ @dataclass
65
+ class AgentConfig:
66
+ """Configuration for agent personality and behavior."""
67
+
68
+ # Agent identity
69
+ personality: str = "balanced" # "aggressive", "defensive", "balanced", "trading"
70
+ risk_tolerance: float = 0.5 # 0.0 (conservative) to 1.0 (risky)
71
+
72
+ # Strategic preferences
73
+ focus_on_settlements: float = 0.6 # Relative priority
74
+ focus_on_cities: float = 0.7
75
+ focus_on_roads: float = 0.5
76
+ focus_on_dev_cards: float = 0.6
77
+
78
+ # Trading behavior
79
+ trade_willingness: float = 0.5 # 0.0 (never trades) to 1.0 (trades often)
80
+ trade_fairness: float = 0.7 # How fair are trade offers
81
+
82
+ # Social behavior
83
+ chat_frequency: float = 0.3 # How often to send chat messages
84
+ use_emojis: bool = True
85
+ chattiness: str = "medium" # "quiet", "medium", "chatty"
86
+
87
+ # Custom instructions
88
+ custom_instructions: Optional[str] = None # Additional instructions for this agent
89
+
90
+
91
+ @dataclass
92
+ class MemoryConfig:
93
+ """Configuration for agent memory system."""
94
+
95
+ # Short-term memory
96
+ short_term_turns: int = 5 # Remember last N turns
97
+
98
+ # Chat history
99
+ chat_history_size: int = 10 # Keep last N messages
100
+ enable_chat_summarization: bool = True
101
+ chat_summary_threshold: int = 10 # Summarize when reaching N messages
102
+
103
+ # Summarization settings
104
+ summarization_provider: str = "gemini"
105
+ summarization_model: str = "gemini-2.0-flash-exp"
106
+ summarization_max_tokens: int = 500
107
+
108
+ # Memory persistence
109
+ save_memory_to_file: bool = True
110
+ memory_file_path: str = "agent_memory.json"
111
+
112
+ # Memory limits
113
+ max_strategic_notes: int = 20
114
+ max_observations: int = 50
115
+
116
+
117
+ @dataclass
118
+ class DebugConfig:
119
+ """Configuration for debugging and logging."""
120
+
121
+ # Logging levels
122
+ debug_mode: bool = False
123
+ log_prompts: bool = True
124
+ log_responses: bool = True
125
+ log_decisions: bool = True
126
+
127
+ # Log file settings
128
+ log_to_file: bool = True
129
+ log_directory: str = "logs/ai_agents"
130
+ log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
131
+
132
+ # Performance monitoring
133
+ track_decision_time: bool = True
134
+ track_token_usage: bool = True
135
+
136
+ # Development helpers
137
+ save_game_states: bool = False # Save game states for analysis
138
+ game_states_directory: str = "logs/game_states"
139
+
140
+
141
+ @dataclass
142
+ class AIConfig:
143
+ """
144
+ Main configuration class for AI agents.
145
+
146
+ This class aggregates all configuration sections and provides
147
+ methods for loading, saving, and accessing configuration values.
148
+ """
149
+
150
+ llm: LLMConfig = field(default_factory=LLMConfig)
151
+ agent: AgentConfig = field(default_factory=AgentConfig)
152
+ memory: MemoryConfig = field(default_factory=MemoryConfig)
153
+ debug: DebugConfig = field(default_factory=DebugConfig)
154
+
155
+ # Metadata
156
+ config_version: str = "1.0"
157
+ agent_name: str = "AI Agent"
158
+
159
+ @classmethod
160
+ def from_file(cls, file_path: str) -> "AIConfig":
161
+ """
162
+ Load configuration from a YAML file.
163
+
164
+ Args:
165
+ file_path: Path to the YAML configuration file
166
+
167
+ Returns:
168
+ AIConfig instance with loaded settings
169
+
170
+ Raises:
171
+ FileNotFoundError: If config file doesn't exist
172
+ yaml.YAMLError: If config file is invalid
173
+ """
174
+ config_path = Path(file_path)
175
+
176
+ if not config_path.exists():
177
+ raise FileNotFoundError(f"Configuration file not found: {file_path}")
178
+
179
+ with open(config_path, 'r', encoding='utf-8') as f:
180
+ data = yaml.safe_load(f)
181
+
182
+ return cls.from_dict(data)
183
+
184
+ @classmethod
185
+ def from_dict(cls, data: Dict[str, Any]) -> "AIConfig":
186
+ """
187
+ Create configuration from a dictionary.
188
+
189
+ Args:
190
+ data: Dictionary with configuration values
191
+
192
+ Returns:
193
+ AIConfig instance
194
+ """
195
+ # Extract nested configs
196
+ llm_data = data.get('llm', {})
197
+ agent_data = data.get('agent', {})
198
+ memory_data = data.get('memory', {})
199
+ debug_data = data.get('debug', {})
200
+
201
+ return cls(
202
+ llm=LLMConfig(**llm_data),
203
+ agent=AgentConfig(**agent_data),
204
+ memory=MemoryConfig(**memory_data),
205
+ debug=DebugConfig(**debug_data),
206
+ config_version=data.get('config_version', '1.0'),
207
+ agent_name=data.get('agent_name', 'AI Agent')
208
+ )
209
+
210
+ def to_dict(self) -> Dict[str, Any]:
211
+ """
212
+ Convert configuration to dictionary.
213
+
214
+ Returns:
215
+ Dictionary representation of configuration
216
+ """
217
+ return {
218
+ 'config_version': self.config_version,
219
+ 'agent_name': self.agent_name,
220
+ 'llm': asdict(self.llm),
221
+ 'agent': asdict(self.agent),
222
+ 'memory': asdict(self.memory),
223
+ 'debug': asdict(self.debug)
224
+ }
225
+
226
+ def to_file(self, file_path: str):
227
+ """
228
+ Save configuration to a YAML file.
229
+
230
+ Args:
231
+ file_path: Path where to save the configuration
232
+ """
233
+ config_path = Path(file_path)
234
+ config_path.parent.mkdir(parents=True, exist_ok=True)
235
+
236
+ with open(config_path, 'w', encoding='utf-8') as f:
237
+ yaml.dump(self.to_dict(), f, default_flow_style=False, sort_keys=False)
238
+
239
+ def get_api_key(self, provider: Optional[str] = None) -> str:
240
+ """
241
+ Get API key from environment variable.
242
+
243
+ Args:
244
+ provider: Provider name (uses llm.provider if None)
245
+
246
+ Returns:
247
+ API key string
248
+
249
+ Raises:
250
+ ValueError: If API key environment variable is not set
251
+ """
252
+ if provider is None:
253
+ provider = self.llm.provider
254
+
255
+ # Determine environment variable name
256
+ if provider == "gemini":
257
+ env_var = self.llm.api_key_env_var or "GEMINI_API_KEY"
258
+ elif provider == "openai":
259
+ env_var = "OPENAI_API_KEY"
260
+ elif provider == "anthropic":
261
+ env_var = "ANTHROPIC_API_KEY"
262
+ elif provider == "azure":
263
+ env_var = "AZURE_OPENAI_KEY"
264
+ else:
265
+ env_var = self.llm.api_key_env_var or f"{provider.upper()}_API_KEY"
266
+
267
+ api_key = os.getenv(env_var)
268
+
269
+ if not api_key:
270
+ raise ValueError(
271
+ f"API key not found. Please set the {env_var} environment variable."
272
+ )
273
+
274
+ return api_key
275
+
276
+ def validate(self) -> bool:
277
+ """
278
+ Validate configuration values.
279
+
280
+ Returns:
281
+ True if configuration is valid
282
+
283
+ Raises:
284
+ ValueError: If configuration contains invalid values
285
+ """
286
+ # Validate temperature
287
+ if not 0.0 <= self.llm.temperature <= 2.0:
288
+ raise ValueError(f"Temperature must be between 0.0 and 2.0, got {self.llm.temperature}")
289
+
290
+ # Validate token limits
291
+ if self.llm.max_tokens < 100:
292
+ raise ValueError(f"max_tokens must be at least 100, got {self.llm.max_tokens}")
293
+
294
+ # Validate risk tolerance
295
+ if not 0.0 <= self.agent.risk_tolerance <= 1.0:
296
+ raise ValueError(f"risk_tolerance must be between 0.0 and 1.0, got {self.agent.risk_tolerance}")
297
+
298
+ # Validate timeouts
299
+ if self.llm.timeout_seconds < 1:
300
+ raise ValueError(f"timeout_seconds must be at least 1, got {self.llm.timeout_seconds}")
301
+
302
+ # Validate memory settings
303
+ if self.memory.short_term_turns < 1:
304
+ raise ValueError(f"short_term_turns must be at least 1, got {self.memory.short_term_turns}")
305
+
306
+ # Check API key is available (warning, not error)
307
+ try:
308
+ self.get_api_key()
309
+ except ValueError as e:
310
+ print(f"Warning: {e}")
311
+
312
+ return True
313
+
314
+ def __repr__(self) -> str:
315
+ """String representation of configuration."""
316
+ return (
317
+ f"AIConfig(\n"
318
+ f" agent_name='{self.agent_name}',\n"
319
+ f" provider='{self.llm.provider}',\n"
320
+ f" model='{self.llm.model_name}',\n"
321
+ f" personality='{self.agent.personality}',\n"
322
+ f" debug={self.debug.debug_mode}\n"
323
+ f")"
324
+ )
325
+
326
+
327
+ # Convenience function for quick config loading
328
+ def load_config(file_path: Optional[str] = None) -> AIConfig:
329
+ """
330
+ Load AI configuration from file or create default.
331
+
332
+ Args:
333
+ file_path: Path to config file (optional)
334
+
335
+ Returns:
336
+ AIConfig instance
337
+ """
338
+ if file_path and Path(file_path).exists():
339
+ return AIConfig.from_file(file_path)
340
+ else:
341
+ return AIConfig()
pycatan/ai/config_example.yaml ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ============================================================================
2
+ # AI Agent Configuration Example
3
+ # ============================================================================
4
+ # This is an example configuration file for PyCatan AI agents.
5
+ # Copy this file and customize it for your agent.
6
+ #
7
+ # Usage:
8
+ # from pycatan.ai.config import AIConfig
9
+ # config = AIConfig.from_file('my_agent_config.yaml')
10
+ # ============================================================================
11
+
12
+ config_version: "1.0"
13
+ agent_name: "AI Agent" # Name of your agent
14
+
15
+ # ============================================================================
16
+ # LLM Configuration
17
+ # ============================================================================
18
+ llm:
19
+ # Provider selection
20
+ # Options: "gemini", "openai", "anthropic", "azure"
21
+ provider: "gemini"
22
+
23
+ # Model name
24
+ # Gemini: "gemini-2.0-flash-exp", "gemini-1.5-pro", "gemini-1.5-flash"
25
+ # OpenAI: "gpt-4-turbo-preview", "gpt-4", "gpt-3.5-turbo"
26
+ # Anthropic: "claude-3-opus-20240229", "claude-3-sonnet-20240229"
27
+ model_name: "gemini-2.0-flash-exp"
28
+
29
+ # Generation parameters
30
+ temperature: 0.7 # 0.0 (deterministic) to 2.0 (creative)
31
+ max_tokens: 4096 # Maximum tokens in response
32
+ top_p: 0.95 # Nucleus sampling threshold
33
+ top_k: 40 # Top-k sampling (for supported models)
34
+
35
+ # API settings
36
+ # The API key is read from environment variables for security
37
+ # Set GEMINI_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY
38
+ api_key_env_var: "GEMINI_API_KEY"
39
+ api_base_url: null # Custom endpoint (if needed)
40
+
41
+ # Performance settings
42
+ timeout_seconds: 30 # Request timeout
43
+ max_retries: 3 # Number of retry attempts
44
+ retry_delay_seconds: 1.0 # Delay between retries
45
+
46
+ # Tracking
47
+ track_usage: true # Track token usage and costs
48
+ log_requests: true # Log all API requests
49
+
50
+ # ============================================================================
51
+ # Agent Configuration
52
+ # ============================================================================
53
+ agent:
54
+ # Personality types affect decision-making style
55
+ # Options: "aggressive", "defensive", "balanced", "trading"
56
+ personality: "balanced"
57
+
58
+ # Risk tolerance: 0.0 (conservative) to 1.0 (risky)
59
+ risk_tolerance: 0.5
60
+
61
+ # Strategic priorities (0.0 to 1.0)
62
+ # Higher values mean higher priority
63
+ focus_on_settlements: 0.6
64
+ focus_on_cities: 0.7
65
+ focus_on_roads: 0.5
66
+ focus_on_dev_cards: 0.6
67
+
68
+ # Trading behavior
69
+ trade_willingness: 0.5 # 0.0 (never) to 1.0 (always)
70
+ trade_fairness: 0.7 # How fair are trade offers
71
+
72
+ # Social behavior
73
+ chat_frequency: 0.3 # How often to chat (0.0 to 1.0)
74
+ use_emojis: true # Use emojis in chat
75
+ chattiness: "medium" # Options: "quiet", "medium", "chatty"
76
+
77
+ # Custom instructions (optional)
78
+ # Add any additional instructions for this specific agent
79
+ custom_instructions: null
80
+ # Example:
81
+ # custom_instructions: "Focus on building settlements near wheat and ore tiles."
82
+
83
+ # ============================================================================
84
+ # Memory Configuration
85
+ # ============================================================================
86
+ memory:
87
+ # Short-term memory
88
+ short_term_turns: 5 # Remember last N turns
89
+
90
+ # Chat history management
91
+ chat_history_size: 10 # Keep last N messages
92
+ enable_chat_summarization: true # Auto-summarize old chats
93
+ chat_summary_threshold: 10 # Summarize after N messages
94
+
95
+ # Summarization settings
96
+ # Use a smaller/cheaper model for summarization
97
+ summarization_provider: "gemini"
98
+ summarization_model: "gemini-2.0-flash-exp"
99
+ summarization_max_tokens: 500
100
+
101
+ # Memory persistence
102
+ save_memory_to_file: true
103
+ memory_file_path: "agent_memory.json"
104
+
105
+ # Memory limits
106
+ max_strategic_notes: 20 # Maximum strategic notes to keep
107
+ max_observations: 50 # Maximum observations to keep
108
+
109
+ # ============================================================================
110
+ # Debug Configuration
111
+ # ============================================================================
112
+ debug:
113
+ # Debug mode - shows detailed information
114
+ debug_mode: false
115
+
116
+ # Logging options
117
+ log_prompts: true # Log prompts sent to LLM
118
+ log_responses: true # Log LLM responses
119
+ log_decisions: true # Log decision-making process
120
+
121
+ # Log file settings
122
+ log_to_file: true
123
+ log_directory: "logs/ai_agents"
124
+ log_format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
125
+
126
+ # Performance tracking
127
+ track_decision_time: true # Track how long decisions take
128
+ track_token_usage: true # Track token consumption
129
+
130
+ # Development helpers
131
+ save_game_states: false # Save game states for analysis
132
+ game_states_directory: "logs/game_states"
133
+
134
+ # ============================================================================
135
+ # Example Configurations for Different Personalities
136
+ # ============================================================================
137
+ #
138
+ # AGGRESSIVE TRADER:
139
+ # ------------------
140
+ # agent:
141
+ # personality: "trading"
142
+ # risk_tolerance: 0.8
143
+ # trade_willingness: 0.9
144
+ # focus_on_settlements: 0.8
145
+ # chat_frequency: 0.6
146
+ #
147
+ # DEFENSIVE BUILDER:
148
+ # ------------------
149
+ # agent:
150
+ # personality: "defensive"
151
+ # risk_tolerance: 0.3
152
+ # trade_willingness: 0.3
153
+ # focus_on_cities: 0.9
154
+ # focus_on_roads: 0.7
155
+ #
156
+ # DEVELOPMENT CARD SPECIALIST:
157
+ # ----------------------------
158
+ # agent:
159
+ # personality: "balanced"
160
+ # risk_tolerance: 0.6
161
+ # focus_on_dev_cards: 0.9
162
+ # trade_willingness: 0.6
163
+ #
164
+ # ============================================================================