Documentation Index
Fetch the complete documentation index at: https://mintlify.com/salesforce/ai-economist/llms.txt
Use this file to discover all available pages before exploring further.
Foundation defines two concrete agent types, both inheriting from BaseAgent (base/base_agent.py). Every environment contains exactly one BasicPlanner and one or more BasicMobileAgent instances (at least 2).
BasicMobileAgent
Defined in agents/mobiles.py. Represents an individual actor in the economic simulation—one that can move around the 2-D world grid.
# agents/mobiles.py
@agent_registry.add
class BasicMobileAgent(BaseAgent):
"""
A basic mobile agent represents an individual actor in the economic simulation.
"Mobile" refers to agents of this type being able to move around in the 2D world.
"""
name = "BasicMobileAgent"
Agent state
Each agent stores its full state in agent.state, a plain dict with these built-in keys:
| Key | Type | Description |
|---|
loc | [row, col] | 2-D position in the world grid |
inventory | dict | Quantities of each resource owned outright (e.g. {"Wood": 3, "Stone": 20, "Coin": 1002.83}) |
escrow | dict | Resources reserved for a pending transaction (same keys as inventory) |
endogenous | dict | Internal quantities like {"Labor": 30.25} |
Components can inject additional fields into agent.state via get_additional_state_fields().
Convenience properties on BaseAgent:
agent.loc # → [row, col]
agent.inventory # → {"Wood": 3, "Stone": 20, "Coin": 1002.83}
agent.escrow # → {"Wood": 0, "Stone": 1, "Coin": 3}
agent.endogenous # → {"Labor": 30.25}
Inventory and escrow
Escrow lets components hold resources on behalf of an agent while a transaction is pending (e.g. a sell order in ContinuousDoubleAuction). The agent cannot use escrowed resources for other purposes.
# Move 1 unit of Wood from inventory into escrow
agent.inventory_to_escrow("Wood", 1)
# Move it back
agent.escrow_to_inventory("Wood", 1)
# Total owned (inventory + escrow)
agent.total_endowment("Wood")
BasicPlanner
Defined in agents/planners.py. Represents a social planner that sets macroeconomic policy (e.g. tax rates, subsidies).
# agents/planners.py
@agent_registry.add
class BasicPlanner(BaseAgent):
"""
A basic planner agent represents a social planner that sets macroeconomic policy.
Unlike the "mobile" agent, the planner does not represent an embodied agent in
the world environment. BasicPlanner modifies the BaseAgent class to remove
location as part of the agent state.
Also unlike the "mobile" agent, the planner agent is expected to be unique --
that is, there should only be 1 planner. For this reason, BasicPlanner ignores
the idx argument during construction and always sets its agent index as "p".
"""
name = "BasicPlanner"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
del self.state["loc"] # planners have no physical location
self._idx = "p" # always indexed as 'p'
The planner has no loc in its state and accessing planner.loc raises AttributeError. Its index is always the string "p".
Agent indexing
Mobile agents are indexed as integers 0, 1, ..., n_agents-1. The planner is always indexed as the string "p".
for agent in env.world.agents: # mobile agents only
print(agent.idx) # 0, 1, 2, ..., n_agents-1
print(env.world.planner.idx) # "p"
Accessing agents
# All agents (mobile + planner) as a list
env.all_agents # → [agent_0, agent_1, ..., planner]
# Mobile agents only
env.world.agents # → [agent_0, agent_1, ...]
# Planner only
env.world.planner # → BasicPlanner instance
# Look up by index
env.get_agent(0) # → BasicMobileAgent with idx=0
env.get_agent("p") # → BasicPlanner
Action spaces
Each agent’s action space is assembled at construction time by registering all applicable components. In single-action mode (default for mobile agents), all component action subspaces are concatenated into a single integer index. In multi-action mode (default for the planner), the agent returns one integer per subspace.
agent.multi_action_mode # True or False
agent.action_spaces # int (single) or int array (multi)
agent._action_names # ["Build", "Gather", ...]
agent.action_dim # {"Build": 2, "Gather": 5, ...}
The NO-OP action is always action index 0 in single-action mode, or index 0 within each subspace in multi-action mode.
# Set a specific component action
agent.set_component_action("Build", 1)
# Read back the action
agent.get_component_action("Build") # → 1
# Reset all actions to NO-OP
agent.reset_actions()
# Fill with random actions (useful for testing)
agent.populate_random_actions()